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