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