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