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