f2773ae01f8c47662423d93873651a2a65dde8f1
[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.getFileContent(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                                   FileUtils.toByteArray(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 getFileCollectionsByFilter(List<FileData> fileDataList, Set<FileData.Type> typeFilter,
224                                                                 TranslationContext translationContext) {
225         FileDataCollection fileDataCollection = new FileDataCollection();
226         Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
227         Set<String> referenced = new HashSet<>();
228
229         for (FileData fileData : filteredFiles.values()) {
230             String fileName = fileData.getFile();
231
232             if (FileData.isHeatFile(fileData.getType())) {
233                 if (fileData.getBase() != null && fileData.getBase()) {
234                     fileDataCollection.addBaseFiles(fileData);
235                 }
236                 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil().yamlToObject(
237                         translationContext.getFileContent(fileName), HeatOrchestrationTemplate.class);
238                 if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
239                     applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext, fileDataCollection,
240                             filteredFiles, referenced);
241                 }
242
243             } else {
244                 fileDataCollection.addArtifactFiles(fileData);
245                 filteredFiles.remove(fileData.getFile());
246             }
247         }
248
249         referenced.forEach(filteredFiles::remove);
250         if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
251             for (FileData fileData : fileDataCollection.getBaseFile()) {
252                 filteredFiles.remove(fileData.getFile());
253             }
254         }
255         fileDataCollection.setAddOnFiles(filteredFiles.values());
256         return fileDataCollection;
257     }
258
259     private static void applyFilterOnFileCollection(HeatOrchestrationTemplate heatOrchestrationTemplate,
260                                                            TranslationContext translationContext,
261                                                            FileDataCollection fileDataCollection,
262                                                            Map<String, FileData> filteredFiles,
263                                                            Set<String> referenced) {
264         List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
265
266         for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
267             if (filenames.contains(resource.getType())) {
268                 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced, resource.getType());
269             } else if (resource.getType().equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
270                 handleResourceGrpNestedFile(resource, translationContext, fileDataCollection, filteredFiles, filenames,
271                         referenced);
272             }
273         }
274     }
275
276     private static void handleResourceGrpNestedFile(Resource resource, TranslationContext translationContext,
277                                                            FileDataCollection fileDataCollection,
278                                                            Map<String, FileData> filteredFiles, List<String> filenames,
279                                                            Set<String> referenced) {
280         Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
281         Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
282         if (innerTypeDef instanceof String) {
283             String internalResourceType = (String) innerTypeDef;
284             if (filenames.contains(internalResourceType)) {
285                 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
286                         internalResourceType);
287             }
288         }
289     }
290
291     private static void handleNestedFile(TranslationContext translationContext, FileDataCollection fileDataCollection,
292                                                 Map<String, FileData> filteredFiles, Set<String> referenced,
293                                                 String nestedFileName) {
294         referenced.add(nestedFileName);
295         fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
296         translationContext.getNestedHeatsFiles().add(nestedFileName);
297     }
298
299     private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
300                                                                          Set<FileData.Type> typesToGet) {
301         Map<String, FileData> filtered = new HashMap<>();
302         fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
303                     .forEach(file -> filtered.put(file.getFile(), file));
304         return filtered;
305     }
306
307     private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
308         return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
309     }
310
311     /**
312      * Extract attached resource id optional.
313      *
314      * @param translateTo  the translate to
315      * @param propertyName the property name
316      * @return the optional
317      */
318     public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo, String propertyName) {
319         Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
320         if (propertyValue == null) {
321             return Optional.empty();
322         }
323         return extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
324                 translateTo.getContext(), propertyValue);
325     }
326
327     /**
328      * Extract attached resource id optional.
329      *
330      * @param heatFileName              the heat file name
331      * @param heatOrchestrationTemplate the heat orchestration template
332      * @param context                   the context
333      * @param propertyValue             the property value
334      * @return the optional
335      */
336     public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
337                                                                                 HeatOrchestrationTemplate heatOrchestrationTemplate,
338                                                                                 TranslationContext context,
339                                                                                 Object propertyValue) {
340
341         Object entity;
342         Object translatedId = null;
343
344         if (Objects.isNull(propertyValue)) {
345             return Optional.empty();
346         }
347
348         ReferenceType referenceType = ReferenceType.OTHER;
349         if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
350             Map<String, Object> propMap = (Map) propertyValue;
351             Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
352             entity = entry.getValue();
353             String key = entry.getKey();
354             referenceType = getReferenceTypeFromAttachedResouce(key);
355
356             if (FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
357                 FunctionTranslator functionTranslator = new FunctionTranslator(getFunctionTranslateTo(null, null,
358                         heatFileName, heatOrchestrationTemplate, context), null, entry.getValue(), null);
359                 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
360                         .translateFunction(functionTranslator);
361                 if (translatedId instanceof String
362                         && !new FunctionTranslator().isResourceSupported((String) translatedId)) {
363                     translatedId = null;
364                 }
365             }
366         } else {
367             translatedId = propertyValue;
368             entity = propertyValue;
369         }
370
371         return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
372     }
373
374     private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
375         ReferenceType referenceType;
376         switch (key) {
377             case GET_RESOURCE:
378                 referenceType = ReferenceType.GET_RESOURCE;
379                 break;
380             case GET_PARAM:
381                 referenceType = ReferenceType.GET_PARAM;
382                 break;
383             case GET_ATTR:
384                 referenceType = ReferenceType.GET_ATTR;
385                 break;
386             default:
387                 referenceType = ReferenceType.OTHER;
388                 break;
389         }
390
391         return referenceType;
392     }
393
394     /**
395      * Gets contrail attached heat resource id.
396      *
397      * @param attachedResource the attached resource
398      * @return the contrail attached heat resource id
399      */
400     public static Optional<String> getContrailAttachedHeatResourceId(AttachedResourceId attachedResource) {
401         if (attachedResource == null) {
402             return Optional.empty();
403         }
404
405         if (attachedResource.isGetResource()) {
406             return Optional.of((String) attachedResource.getEntityId());
407         }
408
409         if (attachedResource.isGetAttr()) {
410             return getResourceId(attachedResource.getEntityId());
411         }
412         return Optional.empty();
413     }
414
415     /**
416      * Extract property optional.
417      *
418      * @param propertyValue the property value
419      * @return the optional
420      */
421     private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
422         Object attachedPropertyVal;
423         if (Objects.isNull(propertyValue)) {
424             return Optional.empty();
425         }
426
427         ReferenceType referenceType = ReferenceType.OTHER;
428         if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
429             Map<String, Object> propMap = (Map) propertyValue;
430             Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
431             attachedPropertyVal = entry.getValue();
432             String key = entry.getKey();
433             switch (key) {
434                 case GET_RESOURCE:
435                     referenceType = ReferenceType.GET_RESOURCE;
436                     break;
437                 case GET_PARAM:
438                     referenceType = ReferenceType.GET_PARAM;
439                     break;
440                 case GET_ATTR:
441                     referenceType = ReferenceType.GET_ATTR;
442                     break;
443                 default:
444                     break;
445             }
446
447         } else {
448             attachedPropertyVal = propertyValue;
449         }
450         return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
451     }
452
453     /**
454      * Map boolean.
455      *
456      * @param nodeTemplate the node template
457      * @param propertyKey  the property key
458      */
459     public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
460         Object value = nodeTemplate.getProperties().get(propertyKey);
461         if (value != null && !(value instanceof Map)) {
462             nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
463         }
464     }
465
466     /**
467      * Map boolean list.
468      *
469      * @param nodeTemplate    the node template
470      * @param propertyListKey the property list key
471      */
472     public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
473         Object listValue = nodeTemplate.getProperties().get(propertyListKey);
474         if (listValue instanceof List) {
475             List booleanList = (List) listValue;
476             for (int i = 0; i < booleanList.size(); i++) {
477                 Object value = booleanList.get(i);
478                 if (value != null && !(value instanceof Map)) {
479                     booleanList.set(i, HeatBoolean.eval(value));
480                 }
481             }
482         }
483     }
484
485
486     /**
487      * Is yml file type boolean.
488      *
489      * @param filename the filename
490      * @return the boolean
491      */
492     public static boolean isYmlFileType(String filename) {
493         String extension = FilenameUtils.getExtension(filename);
494         return "yaml".equalsIgnoreCase(extension) || "yml".equalsIgnoreCase(extension);
495     }
496
497     /**
498      * Is nested resource boolean.
499      *
500      * @param resource the resource
501      * @return the boolean
502      */
503     public static boolean isNestedResource(Resource resource) {
504         String resourceType = resource.getType();
505
506         if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
507             Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
508             if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof String)) {
509                 //currently only resource group which is poinitng to nested heat file is supported
510                 //dynamic type is currently not supported
511                 return false;
512             }
513             String internalResourceType =
514                     (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
515             if (isYamlFile(internalResourceType)) {
516                 return true;
517             }
518         } else if (isYamlFile(resourceType)) {
519             return true;
520         }
521         return false;
522     }
523
524     /**
525      * Checks if the current HEAT resource if of type sub interface.
526      *
527      * @param resource the resource
528      * @return true if the resource is of sub interface type and false otherwise
529      */
530     public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
531         //Check if resource group is a nested resource
532         if (!isNestedResource(resource)) {
533             return false;
534         }
535         Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
536         return nestedHeatFileName.filter(fileName -> isNestedVlanResource(fileName, context)).isPresent();
537     }
538
539     private static boolean isNestedVlanResource(String nestedHeatFileName, TranslationContext translationContext) {
540         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
541                 translationContext.getFileContent(nestedHeatFileName), HeatOrchestrationTemplate.class);
542         return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources()) && nestedHeatOrchestrationTemplate
543                                                                                           .getResources().values()
544                                                                                           .stream().anyMatch(
545                         new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
546     }
547
548     public static Optional<String> getSubInterfaceParentPortNodeTemplateId(TranslateTo subInterfaceTo) {
549         String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
550         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
551                 subInterfaceTo.getContext().getFileContent(subInterfaceResourceType), HeatOrchestrationTemplate.class);
552         if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
553             return Optional.empty();
554         }
555         for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate.getResources().entrySet()) {
556             Resource resource = resourceEntry.getValue();
557             if (isVmiRefsPropertyExists(resource)) {
558                 Object toscaPropertyValue = TranslatorHeatToToscaPropertyConverter
559                                                     .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
560                                                             resourceEntry.getKey(),
561                                                             HeatConstants.VMI_REFS_PROPERTY_NAME,
562                                                             resource.getProperties()
563                                                                     .get(HeatConstants.VMI_REFS_PROPERTY_NAME),
564                                                             resource.getType(), subInterfaceResourceType,
565                                                             nestedHeatOrchestrationTemplate, null,
566                                                             subInterfaceTo.getContext());
567                 return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
568             }
569         }
570         return Optional.empty();
571     }
572
573     private static boolean isVmiRefsPropertyExists(Resource resource) {
574         return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource()
575                                                                                      .equals(resource.getType())
576                        && MapUtils.isNotEmpty(resource.getProperties()) && resource.getProperties().containsKey(
577                 HeatConstants.VMI_REFS_PROPERTY_NAME);
578     }
579
580     public static String getSubInterfaceResourceType(Resource resource) {
581         if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
582             return ((Map) resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
583                            .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME).toString();
584         }
585         return resource.getType();
586     }
587
588     private static Optional<String> getParentNodeTemplateIdFromPropertyValue(Object toscaPropertyValue,
589                                                                                     TranslateTo subInterfaceTo) {
590         if (toscaPropertyValue instanceof List && ((List) toscaPropertyValue).get(0) instanceof Map) {
591             Resource subInterfaceResource = subInterfaceTo.getResource();
592             Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
593             String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT.getDisplayName());
594             Map<String, Object> resourceDefPropertiesMap;
595             if (!isYamlFile(subInterfaceResource.getType())) {
596                 resourceDefPropertiesMap =
597                         (Map) ((Map) subInterfaceResource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
598                                       .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
599             } else {
600                 resourceDefPropertiesMap = subInterfaceResource.getProperties();
601             }
602             Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
603             if (parentPortObj instanceof Map) {
604                 Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
605                 if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions.GET_RESOURCE.getFunction())) {
606                     return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
607                             subInterfaceTo.getHeatOrchestrationTemplate(),
608                             parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
609                             subInterfaceTo.getContext());
610                 }
611             }
612         }
613         return Optional.empty();
614     }
615
616     /**
617      * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
618      * least one or more compute nodes).
619      *
620      * @param resource the resource
621      * @param context  the context
622      * @return true if the resource represents a VFC and false otherwise.
623      */
624     public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
625         Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
626         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
627                 context.getFileContent(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
628         if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
629             for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
630                 if (ConsolidationDataUtil.isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
631                     return true;
632                 }
633             }
634         }
635         return false;
636     }
637
638     /**
639      * Get nested heat file name in case of nested resource.
640      *
641      * @param resource the resource
642      * @return the nested heat file name
643      */
644     private static Optional<String> getNestedHeatFileName(Resource resource) {
645         if (!isNestedResource(resource)) {
646             return Optional.empty();
647         }
648
649         String resourceType = resource.getType();
650
651         if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
652             Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
653             String internalResourceType =
654                     (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
655             return Optional.of(internalResourceType);
656         }
657         return Optional.of(resourceType);
658     }
659
660     /**
661      * Gets nested file.
662      *
663      * @param resource the resource
664      * @return the nested file
665      */
666     public static Optional<String> getNestedFile(Resource resource) {
667         if (!isNestedResource(resource)) {
668             return Optional.empty();
669         }
670         String resourceType = resource.getType();
671         if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
672             Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
673             String internalResourceType =
674                     (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
675             return Optional.of(internalResourceType);
676         } else {
677             return Optional.of(resourceType);
678         }
679     }
680
681     public static boolean isYamlFile(String fileName) {
682         return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
683     }
684
685     /**
686      * Gets resource.
687      *
688      * @param heatOrchestrationTemplate the heat orchestration template
689      * @param resourceId                the resource id
690      * @param heatFileName              the heat file name
691      * @return the resource
692      */
693     public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate, String resourceId,
694                                               String heatFileName) {
695         Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
696         if (resource == null) {
697             throw new CoreException(new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
698         }
699         return resource;
700     }
701
702
703     /**
704      * Get resource type.
705      *
706      * @param resourceId                the resource id
707      * @param heatOrchestrationTemplate heat orchestration template
708      * @param heatFileName              heat file name
709      * @return resource type
710      */
711     public static String getResourceType(String resourceId, HeatOrchestrationTemplate heatOrchestrationTemplate,
712                                                 String heatFileName) {
713         return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName).getType();
714     }
715
716     /**
717      * Is heat file nested boolean.
718      *
719      * @param translateTo  the translate to
720      * @param heatFileName the heat file name
721      * @return the boolean
722      */
723     public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
724         return isHeatFileNested(translateTo.getContext(), heatFileName);
725     }
726
727     public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
728         return context.getNestedHeatsFiles().contains(heatFileName);
729     }
730
731     /**
732      * Extract contrail get resource attached heat resource id optional.
733      *
734      * @param propertyValue the property value
735      * @return the optional
736      */
737     public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(Object propertyValue) {
738         if (propertyValue instanceof Map) {
739             if (((Map) propertyValue).containsKey(GET_ATTR)) {
740                 return getResourceId(((Map) propertyValue).get(GET_ATTR));
741             } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
742                 return getHeatResourceIdFromResource((Map) propertyValue);
743             } else {
744                 Collection valCollection = ((Map) propertyValue).values();
745                 return evaluateHeatResourceId(valCollection);
746             }
747         } else if (propertyValue instanceof List) {
748             return evaluateHeatResourceId((List) propertyValue);
749         }
750         return Optional.empty();
751     }
752
753     private static Optional<String> getResourceId(Object data) {
754         if (data instanceof List && CollectionUtils.size(data) > 1 && FQ_NAME.equals(((List) data).get(1))
755                     && ((List) data).get(0) instanceof String) {
756             return Optional.of((String) ((List) data).get(0));
757         } else {
758             LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
759             return Optional.empty();
760         }
761     }
762
763     private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
764         Object value = propertyValue.get(GET_RESOURCE);
765         if (value instanceof String) {
766             return Optional.of((String) value);
767         } else {
768             LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
769             return Optional.empty();
770         }
771     }
772
773     private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
774         for (Object prop : propertyValue) {
775             Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
776             if (ret.isPresent()) {
777                 return ret;
778             }
779         }
780         return Optional.empty();
781     }
782
783     /**
784      * Gets tosca service model.
785      *
786      * @param context translation context
787      * @return the tosca service model
788      */
789     public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
790         Map<String, String> metadata = new HashMap<>();
791         metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
792         return getToscaServiceModel(context, metadata);
793     }
794
795     /**
796      * Gets tosca service model.
797      *
798      * @param context                 translation context
799      * @param entryDefinitionMetadata template name of the entry definition servie template
800      * @return the tosca service model
801      */
802     private static ToscaServiceModel getToscaServiceModel(TranslationContext context,
803                                                                  Map<String, String> entryDefinitionMetadata) {
804         Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(context.getGlobalServiceTemplates());
805         Collection<ServiceTemplate> tmpServiceTemplates = context.getTranslatedServiceTemplates().values();
806         for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
807             ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
808         }
809         return new ToscaServiceModel(null, serviceTemplates,
810                                             ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
811     }
812
813     /**
814      * Gets service template from context.
815      *
816      * @param serviceTemplateFileName the service template file name
817      * @param context                 the context
818      * @return the service template from context
819      */
820     public static Optional<ServiceTemplate> getServiceTemplateFromContext(String serviceTemplateFileName,
821                                                                                  TranslationContext context) {
822         for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
823             if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
824                 return Optional.of(serviceTemplate);
825             }
826         }
827         return Optional.empty();
828     }
829
830     /**
831      * Adding link requerment from port node template to network node template.
832      *
833      * @param portNodeTemplate    port node template
834      * @param networkTranslatedId network node template id
835      */
836     public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
837                                                                            String networkTranslatedId) {
838         RequirementAssignment requirement = new RequirementAssignment();
839         requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
840         requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
841         requirement.setNode(networkTranslatedId);
842         DataModelUtil.addRequirementAssignment(portNodeTemplate, ToscaConstants.LINK_REQUIREMENT_ID, requirement);
843         return requirement;
844     }
845
846     /**
847      * Adding binding requerment from sub interface node template to interface (port) node template.
848      *
849      * @param subInterfaceNodeTemplate sub interface template
850      * @param interfaceTranslatedId    interface node template id
851      */
852     public static void addBindingReqFromSubInterfaceToInterface(NodeTemplate subInterfaceNodeTemplate,
853                                                                        String interfaceTranslatedId) {
854         RequirementAssignment requirement = new RequirementAssignment();
855         requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
856         requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
857         requirement.setNode(interfaceTranslatedId);
858         DataModelUtil
859                 .addRequirementAssignment(subInterfaceNodeTemplate, ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
860     }
861
862     /**
863      * Get property Parameter Name Value.
864      *
865      * @param property property
866      * @return Parameter name in case the property include "get_param" function
867      */
868     public static Optional<String> getPropertyParameterNameValue(Object property) {
869         if (Objects.isNull(property)) {
870             return Optional.empty();
871         }
872         Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
873         if (extractedProperty.isPresent()) {
874             return getParameterName(extractedProperty.get());
875         }
876         return Optional.empty();
877     }
878
879     private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
880         if (!extractedProperty.isGetParam()) {
881             return Optional.empty();
882         }
883         Object getParamFuncValue = extractedProperty.getPropertyValue();
884         if (getParamFuncValue instanceof String) {
885             return Optional.of((String) getParamFuncValue);
886         } else {
887             return Optional.of((String) ((List) getParamFuncValue).get(0));
888         }
889     }
890
891     public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
892                                                      String heatPropertyName) {
893         return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
894     }
895
896     /**
897      * Gets tosca property name.
898      *
899      * @param translateTo      the translate to
900      * @param heatPropertyName the heat property name
901      * @return the tosca property name
902      */
903     public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
904         return translateTo.getContext()
905                           .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
906     }
907
908     /**
909      * Gets tosca attribute name.
910      *
911      * @param context          the context
912      * @param heatResourceType the heat resource type
913      * @param heatAttrName     the heat attr name
914      * @return the tosca attribute name
915      */
916     public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
917                                                       String heatAttrName) {
918         return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
919     }
920
921     /**
922      * Gets tosca attribute name.
923      *
924      * @param translateTo  the translate to
925      * @param heatAttrName the heat attr name
926      * @return the tosca attribute name
927      */
928     public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
929         return translateTo.getContext()
930                           .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
931     }
932
933     /**
934      * Create init substitution service template service template.
935      *
936      * @param templateName the template name
937      * @return the service template
938      */
939     public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
940         ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
941         Map<String, String> templateMetadata = new HashMap<>();
942         templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
943         nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
944         nestedSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
945         nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
946         List<Map<String, Import>> globalTypesImportList = GlobalTypesGenerator.getGlobalTypesImportList();
947         globalTypesImportList
948                 .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
949         nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
950         return nestedSubstitutionServiceTemplate;
951     }
952
953     /**
954      * Create init global substitution service template service template.
955      *
956      * @return the service template
957      */
958     private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
959         ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
960         Map<String, String> templateMetadata = new HashMap<>();
961         templateMetadata
962                 .put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
963         globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
964         globalSubstitutionServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
965         globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
966         return globalSubstitutionServiceTemplate;
967     }
968
969     /**
970      * Create substitution node type node type.
971      *
972      * @param substitutionServiceTemplate the substitution service template
973      * @return the node type
974      */
975     public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
976         NodeType substitutionNodeType = new NodeType();
977         substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
978         substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
979         substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
980         substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
981         return substitutionNodeType;
982     }
983
984     private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
985         Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
986         Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
987         if (properties == null) {
988             return null;
989         }
990
991         PropertyDefinition propertyDefinition;
992         String toscaPropertyName;
993         for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
994             toscaPropertyName = entry.getKey();
995             propertyDefinition = new PropertyDefinition();
996             ParameterDefinition parameterDefinition =
997                     substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
998             propertyDefinition.setType(parameterDefinition.getType());
999             propertyDefinition.setDescription(parameterDefinition.getDescription());
1000             propertyDefinition.setRequired(parameterDefinition.getRequired());
1001             propertyDefinition.set_default(parameterDefinition.get_default());
1002             propertyDefinition.setConstraints(parameterDefinition.getConstraints());
1003             propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1004             propertyDefinition.setStatus(parameterDefinition.getStatus());
1005             substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1006         }
1007         return substitutionNodeTypeProperties;
1008     }
1009
1010     private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
1011         Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1012         Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
1013         if (attributes == null) {
1014             return null;
1015         }
1016         AttributeDefinition attributeDefinition;
1017         String toscaAttributeName;
1018
1019         for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1020             attributeDefinition = new AttributeDefinition();
1021             toscaAttributeName = entry.getKey();
1022             ParameterDefinition parameterDefinition =
1023                     substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1024             if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1025                 attributeDefinition.setType(parameterDefinition.getType());
1026             } else {
1027                 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1028             }
1029             attributeDefinition.setDescription(parameterDefinition.getDescription());
1030             attributeDefinition.set_default(parameterDefinition.get_default());
1031             attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1032             attributeDefinition.setStatus(parameterDefinition.getStatus());
1033             substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1034         }
1035         return substitutionNodeTypeAttributes;
1036     }
1037
1038     /**
1039      * .
1040      * Create and add substitution mapping to the nested substitution service template, and update
1041      * the subtitution node type accordingly with the exposed requerments and capabilities
1042      *
1043      * @param context                           the translation context
1044      * @param substitutionNodeTypeKey           the substitution node type key
1045      * @param nestedSubstitutionServiceTemplate the nested substitution service template
1046      * @param substitutionNodeType              the substitution node type
1047      */
1048     public static void handleSubstitutionMapping(TranslationContext context, String substitutionNodeTypeKey,
1049                                                         ServiceTemplate nestedSubstitutionServiceTemplate,
1050                                                         NodeType substitutionNodeType) {
1051         Map<String, Map<String, List<String>>> substitutionMapping =
1052                 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType, nestedSubstitutionServiceTemplate,
1053                         context);
1054         //add substitution mapping after capability and requirement expose calculation
1055         nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(DataModelUtil
1056                                                                                                   .createSubstitutionTemplateSubMapping(
1057                                                                                                           substitutionNodeTypeKey,
1058                                                                                                           substitutionNodeType,
1059                                                                                                           substitutionMapping));
1060     }
1061
1062     /**
1063      * Gets node type with flat hierarchy.
1064      *
1065      * @param nodeTypeId      the node type id
1066      * @param serviceTemplate the service template
1067      * @param context         the context
1068      * @return the node type with flat hierarchy
1069      */
1070     public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId, ServiceTemplate serviceTemplate,
1071                                                                TranslationContext context) {
1072         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1073         ToscaServiceModel toscaServiceModel =
1074                 HeatToToscaUtil.getToscaServiceModel(context, serviceTemplate.getMetadata());
1075         return (NodeType) toscaAnalyzerService.getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate,
1076                 toscaServiceModel).getFlatEntity();
1077     }
1078
1079
1080     /**
1081      * Create abstract substitution node template.
1082      *
1083      * @param translateTo             the translate to
1084      * @param templateName            the template name
1085      * @param substitutionNodeTypeKey the substitution node type key
1086      * @return the abstract substitute node template
1087      */
1088     public static NodeTemplate createAbstractSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1089                                                                              String substitutionNodeTypeKey) {
1090         NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1091         List<String> directiveList = new ArrayList<>();
1092         directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1093         substitutionNodeTemplate.setDirectives(directiveList);
1094         substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1095         substitutionNodeTemplate.setProperties(
1096                 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate, templateName));
1097         return substitutionNodeTemplate;
1098     }
1099
1100
1101     /**
1102      * Checks if the source and target resource is a valid candidate for adding tosca dependency
1103      * relationship.
1104      *
1105      * @param sourceResource   the source resource
1106      * @param targetResource   the target resource
1107      * @param dependencyEntity the dependency entity
1108      * @return true if the candidate resources are a valid combination for the dependency relationship
1109      * and false otherwise
1110      */
1111     public static boolean isValidDependsOnCandidate(Resource sourceResource, Resource targetResource,
1112                                                            ConsolidationEntityType dependencyEntity,
1113                                                            TranslationContext context) {
1114         dependencyEntity.setEntityType(sourceResource, targetResource, context);
1115         ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1116         ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1117
1118         return ConsolidationTypesConnectivity.isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
1119     }
1120
1121     private static Map<String, Object> managerSubstitutionNodeTemplateProperties(TranslateTo translateTo,
1122                                                                                         Template template,
1123                                                                                         String templateName) {
1124         Map<String, Object> substitutionProperties = new HashMap<>();
1125         Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1126         if (Objects.nonNull(heatProperties)) {
1127             for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1128                 Object property = TranslatorHeatToToscaPropertyConverter
1129                                           .getToscaPropertyValue(translateTo.getServiceTemplate(),
1130                                                   translateTo.getTranslatedId(), entry.getKey(), entry.getValue(), null,
1131                                                   translateTo.getHeatFileName(),
1132                                                   translateTo.getHeatOrchestrationTemplate(), template,
1133                                                   translateTo.getContext());
1134                 substitutionProperties.put(entry.getKey(), property);
1135             }
1136         }
1137         return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1138     }
1139
1140     private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1141                                                                               Map<String, Object> substitutionProperties) {
1142         Map<String, Object> innerProps = new HashMap<>();
1143         innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1144                 ToscaUtil.getServiceTemplateFileName(templateName));
1145         substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1146         return substitutionProperties;
1147     }
1148
1149     private static Map<String, Map<String, List<String>>> getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1150                                                                                                                 ServiceTemplate substitutionServiceTemplate,
1151                                                                                                                 TranslationContext context) {
1152         Map<String, NodeTemplate> nodeTemplates =
1153                 substitutionServiceTemplate.getTopology_template().getNode_templates();
1154         String nodeTemplateId;
1155         NodeTemplate nodeTemplate;
1156         String nodeType;
1157         Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1158         if (nodeTemplates == null) {
1159             return substitutionMapping;
1160         }
1161
1162         Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1163         Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1164         substitutionMapping.put("capability", capabilitySubstitutionMapping);
1165         substitutionMapping.put("requirement", requirementSubstitutionMapping);
1166         List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1167         Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1168         List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1169         Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition = new HashMap<>();
1170         Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1171         Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1172         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1173
1174         for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1175             nodeTemplateId = entry.getKey();
1176             nodeTemplate = entry.getValue();
1177             nodeType = nodeTemplate.getType();
1178
1179             // get requirements
1180             nodeTypeRequirementsDefinition = getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1181                     requirementSubstitutionMapping, context);
1182             nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1183             fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1184             //set substitution node type requirements
1185             exposedRequirementsDefinition = toscaAnalyzerService
1186                                                     .calculateExposedRequirements(nodeTypeRequirementsDefinition,
1187                                                             nodeTemplateRequirementsAssignment);
1188             DataModelUtil.addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1189                     nodeTemplateId);
1190
1191             //get capabilities
1192             addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping, nodeType,
1193                     nodeTemplateId, substitutionServiceTemplate, context);
1194         }
1195
1196         exposedCapabilitiesDefinition = toscaAnalyzerService
1197                                                 .calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1198                                                         fullFilledRequirementsDefinition);
1199         DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1200         return substitutionMapping;
1201     }
1202
1203     private static void addNodeTypeCapabilitiesToSubMapping(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1204                                                                    Map<String, List<String>> capabilitySubstitutionMapping,
1205                                                                    String type, String templateName,
1206                                                                    ServiceTemplate serviceTemplate,
1207                                                                    TranslationContext context) {
1208         NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1209
1210         if (flatNodeType.getCapabilities() != null) {
1211             flatNodeType.getCapabilities().entrySet().stream().forEach(
1212                     capabilityNodeEntry -> addCapabilityToSubMapping(templateName, capabilityNodeEntry,
1213                             nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping));
1214         }
1215     }
1216
1217     private static void addCapabilityToSubMapping(String templateName,
1218                                                          Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
1219                                                          Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1220                                                          Map<String, List<String>> capabilitySubstitutionMapping) {
1221         String capabilityKey;
1222         List<String> capabilityMapping;
1223         capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
1224         nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1225         capabilityMapping = new ArrayList<>();
1226         capabilityMapping.add(templateName);
1227         capabilityMapping.add(capabilityNodeEntry.getKey());
1228         capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1229     }
1230
1231     private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(String type, String templateName,
1232                                                                                    ServiceTemplate serviceTemplate,
1233                                                                                    Map<String, List<String>> requirementSubstitutionMapping,
1234                                                                                    TranslationContext context) {
1235         List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1236         NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1237         List<String> requirementMapping;
1238
1239         if (flatNodeType.getRequirements() == null) {
1240             return requirementList;
1241         }
1242
1243         for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1244             for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap.entrySet()) {
1245                 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1246                 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil.yamlToObject(
1247                         toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1248                         RequirementDefinition.class);
1249                 if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
1250                     requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1251                 }
1252                 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1253                 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1254                 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1255                 requirementMapping = new ArrayList<>();
1256                 requirementMapping.add(templateName);
1257                 requirementMapping.add(requirementNodeEntry.getKey());
1258                 requirementSubstitutionMapping
1259                         .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
1260                 if (Objects.isNull(requirementNodeEntryValue.getNode())) {
1261                     requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1262                 }
1263             }
1264         }
1265         return requirementList;
1266     }
1267
1268     /**
1269      * Fetch global substitution service template service template.
1270      *
1271      * @param serviceTemplate the service template
1272      * @param context         the context
1273      * @return the service template
1274      */
1275     public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(ServiceTemplate serviceTemplate,
1276                                                                                 TranslationContext context) {
1277         ServiceTemplate globalSubstitutionServiceTemplate =
1278                 context.getTranslatedServiceTemplates().get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1279         if (globalSubstitutionServiceTemplate == null) {
1280             globalSubstitutionServiceTemplate = HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1281             context.getTranslatedServiceTemplates()
1282                    .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, globalSubstitutionServiceTemplate);
1283         }
1284         boolean isImportAddedToServiceTemplate = DataModelUtil
1285                                                          .isImportAddedToServiceTemplate(serviceTemplate.getImports(),
1286                                                                  Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1287         if (!isImportAddedToServiceTemplate) {
1288             serviceTemplate.getImports()
1289                            .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1290         }
1291         return globalSubstitutionServiceTemplate;
1292     }
1293
1294     public static List<Map<String, Import>> createImportList(String templateName) {
1295         List<Map<String, Import>> imports = new ArrayList<>();
1296         Map<String, Import> importsMap = new HashMap<>();
1297         importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1298         imports.add(importsMap);
1299         return imports;
1300     }
1301
1302     /**
1303      * Create service template import import.
1304      *
1305      * @param serviceTemplate the service template
1306      * @return the import
1307      */
1308     public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1309         Import serviceTemplateImport = new Import();
1310         serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1311         return serviceTemplateImport;
1312     }
1313
1314     /**
1315      * Create service template import import.
1316      *
1317      * @param metadataTemplateName the service template name
1318      * @return the import
1319      */
1320     private static Import createServiceTemplateImport(String metadataTemplateName) {
1321         Import serviceTemplateImport = new Import();
1322         serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1323         return serviceTemplateImport;
1324     }
1325
1326     public static ToscaServiceModel createToscaServiceModel(ServiceTemplate entryDefinitionServiceTemplate,
1327                                                                    TranslationContext translationContext) {
1328         return new ToscaServiceModel(getCsarArtifactFiles(translationContext), getServiceTemplates(translationContext),
1329                                             ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1330     }
1331
1332     private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1333         FileContentHandler artifactFiles = new FileContentHandler();
1334         artifactFiles.setFiles(translationContext.getFiles());
1335         artifactFiles.setFiles(translationContext.getExternalArtifacts());
1336
1337         HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1338         heatTreeManager.createTree();
1339         ValidationStructureList validationStructureList = new ValidationStructureList(heatTreeManager.getTree());
1340         byte[] validationStructureFile =
1341                 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1342         artifactFiles.addFile("HEAT.meta", validationStructureFile);
1343         return artifactFiles;
1344     }
1345
1346
1347     private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext translationContext) {
1348         List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1349         serviceTemplates.addAll(GlobalTypesGenerator.getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
1350         serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1351         Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1352
1353         for (ServiceTemplate template : serviceTemplates) {
1354             serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1355         }
1356         return serviceTemplatesMap;
1357     }
1358
1359     public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
1360         if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext()) && isSubInterfaceBoundToPort(
1361                 translateTo)) {
1362             return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
1363         }
1364         return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
1365     }
1366
1367     private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
1368         return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
1369     }
1370
1371     //Method evaluate the  network role from sub interface node template id, designed considering
1372     // only single sub interface present in nested file else it will return null
1373     public static Optional<String> getNetworkRoleFromSubInterfaceId(Resource resource,
1374                                                                            TranslationContext translationContext) {
1375         Optional<String> networkRole = Optional.empty();
1376         Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
1377
1378         if (!nestedHeatFileName.isPresent()) {
1379             return networkRole;
1380         }
1381
1382         HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
1383                 translationContext.getFileContent(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
1384
1385         if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
1386             ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
1387                     new ContrailV2VirtualMachineInterfaceHelper();
1388             Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
1389                     nestedHeatOrchestrationTemplate.getResources().entrySet().stream()
1390                                                    .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
1391                                                                                     .isVlanSubInterfaceResource(
1392                                                                                             resourceEntry.getValue()))
1393                                                    .findFirst();
1394             if (vlanSubInterfaceResource.isPresent()) {
1395                 Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
1396                 networkRole = extractNetworkRoleFromSubInterfaceId(vlanSubInterfaceResourceEntry.getKey(),
1397                         vlanSubInterfaceResourceEntry.getValue().getType());
1398             }
1399         }
1400         return networkRole;
1401     }
1402
1403 }