2  * Copyright © 2016-2018 European Support Limited
 
   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
 
   8  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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.
 
  17 package org.openecomp.sdc.translator.services.heattotosca;
 
  19 import org.apache.commons.collections4.CollectionUtils;
 
  20 import org.apache.commons.collections4.MapUtils;
 
  21 import org.apache.commons.io.FilenameUtils;
 
  22 import org.openecomp.core.translator.api.HeatToToscaTranslator;
 
  23 import org.openecomp.core.translator.datatypes.TranslatorOutput;
 
  24 import org.openecomp.core.translator.factory.HeatToToscaTranslatorFactory;
 
  25 import org.openecomp.core.utilities.file.FileContentHandler;
 
  26 import org.openecomp.core.utilities.file.FileUtils;
 
  27 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
 
  28 import org.openecomp.core.validation.util.MessageContainerUtil;
 
  29 import org.openecomp.sdc.common.errors.CoreException;
 
  30 import org.openecomp.sdc.common.togglz.ToggleableFeature;
 
  31 import org.openecomp.sdc.common.utils.SdcCommon;
 
  32 import org.openecomp.sdc.datatypes.error.ErrorLevel;
 
  33 import org.openecomp.sdc.datatypes.error.ErrorMessage;
 
  34 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
 
  35 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
 
  36 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
 
  37 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
 
  38 import org.openecomp.sdc.heat.datatypes.model.Resource;
 
  39 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
 
  40 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
 
  41 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
 
  42 import org.openecomp.sdc.heat.services.HeatConstants;
 
  43 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
 
  44 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
 
  45 import org.openecomp.sdc.logging.api.Logger;
 
  46 import org.openecomp.sdc.logging.api.LoggerFactory;
 
  47 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
 
  48 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
 
  49 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
 
  50 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
 
  51 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
 
  52 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
 
  53 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
 
  54 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
 
  55 import org.openecomp.sdc.tosca.datatypes.model.Import;
 
  56 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
 
  57 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
 
  58 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
 
  59 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
 
  60 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
 
  61 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
 
  62 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
 
  63 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
 
  64 import org.openecomp.sdc.tosca.datatypes.model.Template;
 
  65 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
 
  66 import org.openecomp.sdc.tosca.services.DataModelUtil;
 
  67 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
 
  68 import org.openecomp.sdc.tosca.services.ToscaConstants;
 
  69 import org.openecomp.sdc.tosca.services.ToscaExtensionYamlUtil;
 
  70 import org.openecomp.sdc.tosca.services.ToscaUtil;
 
  71 import org.openecomp.sdc.tosca.services.YamlUtil;
 
  72 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
 
  73 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedPropertyVal;
 
  74 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
 
  75 import org.openecomp.sdc.translator.datatypes.heattotosca.ReferenceType;
 
  76 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
 
  77 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
 
  78 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
 
  79 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
 
  80 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
 
  81 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailV2VirtualMachineInterfaceHelper;
 
  82 import org.openecomp.sdc.translator.services.heattotosca.helper.FunctionTranslationHelper;
 
  83 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
 
  84 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
 
  86 import java.io.IOException;
 
  87 import java.io.InputStream;
 
  88 import java.util.ArrayList;
 
  89 import java.util.Collection;
 
  90 import java.util.HashMap;
 
  91 import java.util.HashSet;
 
  92 import java.util.List;
 
  94 import java.util.Objects;
 
  95 import java.util.Optional;
 
  97 import java.util.regex.Matcher;
 
  98 import java.util.regex.Pattern;
 
  99 import java.util.stream.Collectors;
 
 102  * The type Heat to tosca util.
 
 104 public class HeatToToscaUtil {
 
 106   private static final Logger LOGGER = LoggerFactory.getLogger(HeatToToscaUtil.class);
 
 107   public static final String FQ_NAME = "fq_name";
 
 108   public static final String GET_PARAM = "get_param";
 
 109   private static final String GET_ATTR = "get_attr";
 
 110   private static final String GET_RESOURCE = "get_resource";
 
 111   private static final String VMI = "vmi";
 
 112   private static final String NEUTRON_PORT_IDENTIFIER = "port";
 
 113   private static final String UNDERSCORE = "_";
 
 116    * Load and translate template data translator output.
 
 118    * @param fileNameContentMap the file name content map
 
 119    * @return the translator output
 
 121   public static TranslatorOutput loadAndTranslateTemplateData(
 
 122       FileContentHandler fileNameContentMap) {
 
 123     HeatToToscaTranslator heatToToscaTranslator =
 
 124         HeatToToscaTranslatorFactory.getInstance().createInterface();
 
 126     try (InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME)) {
 
 127       heatToToscaTranslator.addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
 
 128     } catch (IOException e) {
 
 129       throw new RuntimeException("Failed to read manifest", e);
 
 132     fileNameContentMap.getFileList().stream()
 
 133         .filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME))).forEach(
 
 134         fileName -> heatToToscaTranslator
 
 135             .addFile(fileName, FileUtils.toByteArray
 
 136                 (fileNameContentMap.getFileContent(fileName))));
 
 138     Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
 
 139     if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
 
 140       TranslatorOutput translatorOutput = new TranslatorOutput();
 
 141       translatorOutput.setErrorMessages(errors);
 
 142       return translatorOutput;
 
 145     try (InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap)) {
 
 146       heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
 
 147       return heatToToscaTranslator.translate();
 
 148     } catch (IOException e) {
 
 149       // rethrow as a RuntimeException to keep the signature backward compatible
 
 150       throw new RuntimeException("Failed to read Heat template tree", e);
 
 155   private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
 
 156     HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
 
 157     heatTreeManager.createTree();
 
 158     HeatStructureTree tree = heatTreeManager.getTree();
 
 159     ValidationStructureList validationStructureList = new ValidationStructureList(tree);
 
 160     return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
 
 164    * Build list of files to search optional.
 
 166    * @param heatFileName  the heat file name
 
 167    * @param filesDataList the files data list
 
 168    * @param types         the types
 
 169    * @return the optional
 
 171   public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
 
 172                                                                   List<FileData> filesDataList,
 
 173                                                                   FileData.Type... types) {
 
 174     List<FileData> list = new ArrayList<>(filesDataList);
 
 175     Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
 
 176     if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
 
 177       list.addAll(resourceFileData.get().getData());
 
 179     return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
 
 183    * Gets filtered list of file data by types.
 
 185    * @param filesToSearch the files to search
 
 186    * @param types         the types
 
 187    * @return the filtered list of file data by types
 
 189   public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
 
 190                                                                 FileData.Type... types) {
 
 191     return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types))
 
 192         .collect(Collectors.toList());
 
 196    * Gets file data from the list according to the input heat file name.
 
 198    * @param heatFileName the heat file name
 
 199    * @param fileDataList the file data list
 
 200    * @return the file data
 
 202   public static Optional<FileData> getFileData(String heatFileName,
 
 203                                                Collection<FileData> fileDataList) {
 
 204     for (FileData file : fileDataList) {
 
 205       if (file.getFile().equals(heatFileName)) {
 
 206         return Optional.of(file);
 
 209     return Optional.empty();
 
 213    * Gets file data which is supported by the translator, from the context according the input heat
 
 216    * @param heatFileName the heat file name
 
 217    * @param context      the translation context
 
 218    * @return the file data
 
 220   public static FileData getFileData(String heatFileName, TranslationContext context) {
 
 222     List<FileData> fileDataList = context.getManifest().getContent().getData();
 
 223     for (FileData fileData : fileDataList) {
 
 224       if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType())
 
 225           && fileData.getFile().equals(heatFileName)) {
 
 232   static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList,
 
 233                                                        Set<FileData.Type> typeFilter,
 
 234                                                        TranslationContext translationContext) {
 
 235     FileDataCollection fileDataCollection = new FileDataCollection();
 
 236     Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
 
 237     Set<String> referenced = new HashSet<>();
 
 239     for (FileData fileData : filteredFiles.values()) {
 
 240       String fileName = fileData.getFile();
 
 242       if (FileData.isHeatFile(fileData.getType())) {
 
 243         if (fileData.getBase() != null && fileData.getBase()) {
 
 244           fileDataCollection.addBaseFiles(fileData);
 
 246         HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
 
 247             .yamlToObject(translationContext.getFileContent(fileName),
 
 248                 HeatOrchestrationTemplate.class);
 
 249         if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
 
 250           applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext,
 
 251               fileDataCollection, filteredFiles, referenced);
 
 255         fileDataCollection.addArtifactFiles(fileData);
 
 256         filteredFiles.remove(fileData.getFile());
 
 260     referenced.forEach(filteredFiles::remove);
 
 261     if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
 
 262       for (FileData fileData : fileDataCollection.getBaseFile()) {
 
 263         filteredFiles.remove(fileData.getFile());
 
 266     fileDataCollection.setAddOnFiles(filteredFiles.values());
 
 267     return fileDataCollection;
 
 270   private static void applyFilterOnFileCollection(
 
 271       HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 272       TranslationContext translationContext,
 
 273       FileDataCollection fileDataCollection, Map<String, FileData> filteredFiles,
 
 274       Set<String> referenced) {
 
 275     List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
 
 277     for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
 
 278       if (filenames.contains(resource.getType())) {
 
 279         handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
 
 281       } else if (resource.getType()
 
 282           .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 283         handleResourceGrpNestedFile(resource, translationContext, fileDataCollection,
 
 284             filteredFiles, filenames, referenced);
 
 289   private static void handleResourceGrpNestedFile(Resource resource,
 
 290                                                   TranslationContext translationContext,
 
 291                                                   FileDataCollection fileDataCollection,
 
 292                                                   Map<String, FileData> filteredFiles,
 
 293                                                   List<String> filenames,
 
 294                                                   Set<String> referenced) {
 
 295     Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 296     Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 297     if (innerTypeDef instanceof String) {
 
 298       String internalResourceType = (String) innerTypeDef;
 
 299       if (filenames.contains(internalResourceType)) {
 
 300         handleNestedFile(translationContext, fileDataCollection, filteredFiles,
 
 301             referenced, internalResourceType);
 
 306   private static void handleNestedFile(TranslationContext translationContext,
 
 307                                        FileDataCollection fileDataCollection,
 
 308                                        Map<String, FileData> filteredFiles, Set<String> referenced,
 
 309                                        String nestedFileName) {
 
 310     referenced.add(nestedFileName);
 
 311     fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
 
 312     translationContext.getNestedHeatsFiles().add(nestedFileName);
 
 315   private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
 
 316                                                                 Set<FileData.Type> typesToGet) {
 
 317     Map<String, FileData> filtered = new HashMap<>();
 
 318     fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
 
 319         .forEach(file -> filtered.put(file.getFile(), file));
 
 323   private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
 
 324     return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
 
 328    * Extract attached resource id optional.
 
 330    * @param translateTo  the translate to
 
 331    * @param propertyName the property name
 
 332    * @return the optional
 
 334   public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
 
 335                                                                        String propertyName) {
 
 336     Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
 
 337     if (propertyValue == null) {
 
 338       return Optional.empty();
 
 340     return extractAttachedResourceId(translateTo.getHeatFileName(),
 
 341         translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(), propertyValue);
 
 345    * Extract attached resource id optional.
 
 347    * @param heatFileName              the heat file name
 
 348    * @param heatOrchestrationTemplate the heat orchestration template
 
 349    * @param context                   the context
 
 350    * @param propertyValue             the property value
 
 351    * @return the optional
 
 353   public static Optional<AttachedResourceId> extractAttachedResourceId(
 
 355       HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 356       TranslationContext context,
 
 357       Object propertyValue) {
 
 362     if (Objects.isNull(propertyValue)) {
 
 363       return Optional.empty();
 
 366     ReferenceType referenceType = ReferenceType.OTHER;
 
 367     if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
 
 368       Map<String, Object> propMap = (Map) propertyValue;
 
 369       Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
 
 370       entity = entry.getValue();
 
 371       String key = entry.getKey();
 
 372       referenceType = getReferenceTypeFromAttachedResouce(key);
 
 374       if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
 
 377         translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
 
 378             .translateFunction(null, null, null, entry.getKey(), entry.getValue(), heatFileName,
 
 379                 heatOrchestrationTemplate, null, context);
 
 381       if (translatedId instanceof String
 
 382           && !FunctionTranslationHelper.isResourceSupported((String) translatedId)) {
 
 387       translatedId = propertyValue;
 
 388       entity = propertyValue;
 
 391     return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
 
 394   private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
 
 395     ReferenceType referenceType;
 
 398         referenceType = ReferenceType.GET_RESOURCE;
 
 401         referenceType = ReferenceType.GET_PARAM;
 
 404         referenceType = ReferenceType.GET_ATTR;
 
 407         referenceType = ReferenceType.OTHER;
 
 411     return referenceType;
 
 415    * Gets contrail attached heat resource id.
 
 417    * @param attachedResource the attached resource
 
 418    * @return the contrail attached heat resource id
 
 420   public static Optional<String> getContrailAttachedHeatResourceId(
 
 421       AttachedResourceId attachedResource) {
 
 422     if (attachedResource == null) {
 
 423       return Optional.empty();
 
 426     if (attachedResource.isGetResource()) {
 
 427       return Optional.of((String) attachedResource.getEntityId());
 
 430     if (attachedResource.isGetAttr()) {
 
 431       return getResourceId(attachedResource.getEntityId());
 
 433     return Optional.empty();
 
 437    * Extract property optional.
 
 439    * @param propertyValue the property value
 
 440    * @return the optional
 
 442   public static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
 
 443     Object attachedPropertyVal;
 
 444     if (Objects.isNull(propertyValue)) {
 
 445       return Optional.empty();
 
 448     ReferenceType referenceType = ReferenceType.OTHER;
 
 449     if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
 
 450       Map<String, Object> propMap = (Map) propertyValue;
 
 451       Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
 
 452       attachedPropertyVal = entry.getValue();
 
 453       String key = entry.getKey();
 
 456           referenceType = ReferenceType.GET_RESOURCE;
 
 459           referenceType = ReferenceType.GET_PARAM;
 
 462           referenceType = ReferenceType.GET_ATTR;
 
 469       attachedPropertyVal = propertyValue;
 
 471     return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
 
 477    * @param nodeTemplate the node template
 
 478    * @param propertyKey  the property key
 
 480   public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
 
 481     Object value = nodeTemplate.getProperties().get(propertyKey);
 
 482     if (value != null && !(value instanceof Map)) {
 
 483       nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
 
 490    * @param nodeTemplate    the node template
 
 491    * @param propertyListKey the property list key
 
 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));
 
 508    * Is yml file type boolean.
 
 510    * @param filename the filename
 
 511    * @return the boolean
 
 513   public static boolean isYmlFileType(String filename) {
 
 514     String extension = FilenameUtils.getExtension(filename);
 
 515     return "yaml".equalsIgnoreCase(extension)
 
 516         || "yml".equalsIgnoreCase(extension);
 
 520    * Is nested resource boolean.
 
 522    * @param resource the resource
 
 523    * @return the boolean
 
 525   public static boolean isNestedResource(Resource resource) {
 
 526     String resourceType = resource.getType();
 
 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(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof
 
 532         //currently only resource group which is poinitng to nested heat file is supported
 
 533         //dynamic type is currently not supported
 
 536       String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
 
 537           .RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 538       if (isYamlFile(internalResourceType)) {
 
 541     } else if (isYamlFile(resourceType)) {
 
 548    * Checks if the current HEAT resource if of type sub interface.
 
 550    * @param resource the resource
 
 551    * @return true if the resource is of sub interface type and false otherwise
 
 553   public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
 
 554     if (!ToggleableFeature.VLAN_TAGGING.isActive()) {
 
 555       //Remove this once feature is stable and moved to production
 
 558     //Check if resource group is a nested resource
 
 559     if (!isNestedResource(resource)) {
 
 562     Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
 
 563     return nestedHeatFileName.filter(fileName ->
 
 564         isNestedVlanResource(fileName, context)).isPresent();
 
 567   private static boolean isNestedVlanResource(String nestedHeatFileName,
 
 568                                               TranslationContext translationContext) {
 
 569     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
 570         .yamlToObject(translationContext.getFileContent(nestedHeatFileName),
 
 571             HeatOrchestrationTemplate.class);
 
 572     return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())
 
 573         && nestedHeatOrchestrationTemplate.getResources().values().stream()
 
 574         .anyMatch(new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
 
 577   public static Optional<String> getSubInterfaceParentPortNodeTemplateId(TranslateTo subInterfaceTo) {
 
 578     String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
 
 579     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
 580         .yamlToObject(subInterfaceTo.getContext().getFileContent(subInterfaceResourceType),
 
 581             HeatOrchestrationTemplate.class);
 
 582     if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
 
 583       return Optional.empty();
 
 585     for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate
 
 586         .getResources().entrySet()) {
 
 587       Resource resource = resourceEntry.getValue();
 
 588       if (isVmiRefsPropertyExists(resource)) {
 
 589         Object toscaPropertyValue =
 
 590             TranslatorHeatToToscaPropertyConverter.getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
 
 591                 resourceEntry.getKey(), HeatConstants.VMI_REFS_PROPERTY_NAME,
 
 592                 resource.getProperties().get(HeatConstants.VMI_REFS_PROPERTY_NAME),
 
 593                 resource.getType(), subInterfaceResourceType, nestedHeatOrchestrationTemplate,
 
 594                 null, subInterfaceTo.getContext());
 
 595         return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
 
 598     return Optional.empty();
 
 601   private static boolean isVmiRefsPropertyExists(Resource resource) {
 
 602     return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
 
 603         .getHeatResource().equals(resource.getType())
 
 604         && MapUtils.isNotEmpty(resource.getProperties())
 
 605         && resource.getProperties().containsKey(HeatConstants.VMI_REFS_PROPERTY_NAME);
 
 608   public static String getSubInterfaceResourceType(Resource resource) {
 
 609     if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
 
 610       return ((Map) resource.getProperties()
 
 611           .get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
 
 612           .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME)
 
 615     return resource.getType();
 
 618   private static Optional<String> getParentNodeTemplateIdFromPropertyValue(Object toscaPropertyValue,
 
 619                                                                            TranslateTo subInterfaceTo) {
 
 620     if (toscaPropertyValue instanceof List
 
 621         && ((List) toscaPropertyValue).get(0) instanceof Map) {
 
 622       Resource subInterfaceResource = subInterfaceTo.getResource();
 
 623       Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
 
 624       String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT
 
 626       Map<String, Object> resourceDefPropertiesMap;
 
 627       if (!isYamlFile(subInterfaceResource.getType())) {
 
 628         resourceDefPropertiesMap = (Map)((Map) subInterfaceResource
 
 629             .getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
 
 630             .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
 
 632         resourceDefPropertiesMap = subInterfaceResource.getProperties();
 
 634       Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
 
 635       if (parentPortObj instanceof  Map) {
 
 636         Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
 
 637         if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions
 
 638             .GET_RESOURCE.getFunction())) {
 
 639           return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
 
 640               subInterfaceTo.getHeatOrchestrationTemplate(),
 
 641               parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
 
 642               subInterfaceTo.getContext());
 
 646     return Optional.empty();
 
 650    * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
 
 651    * least one or more compute nodes).
 
 653    * @param resource the resource
 
 654    * @param context the context
 
 655    * @return true if the resource represents a VFC and false otherwise.
 
 657   public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
 
 658     Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
 
 659     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
 660         .yamlToObject(context.getFileContent(nestedHeatFileName.get()),
 
 661             HeatOrchestrationTemplate.class);
 
 662     if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
 
 663       for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
 
 664         if (ConsolidationDataUtil
 
 665             .isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
 
 674    * Get nested heat file name in case of nested resource.
 
 676    * @param resource the resource
 
 677    * @return the nested heat file name
 
 679   public static Optional<String> getNestedHeatFileName(Resource resource) {
 
 680     if (!isNestedResource(resource)) {
 
 681       return Optional.empty();
 
 684     String resourceType = resource.getType();
 
 686     if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 687       Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 688       String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
 
 689           .RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 690       return Optional.of(internalResourceType);
 
 692     return Optional.of(resourceType);
 
 698    * @param resource the resource
 
 699    * @return the nested file
 
 701   public static Optional<String> getNestedFile(Resource resource) {
 
 702     if (!isNestedResource(resource)) {
 
 703       return Optional.empty();
 
 705     String resourceType = resource.getType();
 
 706     if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 707       Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 708       String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
 
 709           .RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 710       return Optional.of(internalResourceType);
 
 712       return Optional.of(resourceType);
 
 716   public static boolean isYamlFile(String fileName) {
 
 717     return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
 
 723    * @param heatOrchestrationTemplate the heat orchestration template
 
 724    * @param resourceId                the resource id
 
 725    * @param heatFileName              the heat file name
 
 726    * @return the resource
 
 728   public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 729                                      String resourceId, String heatFileName) {
 
 730     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
 
 731     if (resource == null) {
 
 732       throw new CoreException(
 
 733           new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
 
 742    * @param resourceId                the resource id
 
 743    * @param heatOrchestrationTemplate heat orchestration template
 
 744    * @param heatFileName              heat file name
 
 745    * @return resource type
 
 747   public static String getResourceType(String resourceId,
 
 748                                        HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 749                                        String heatFileName) {
 
 750     return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName)
 
 755    * Is heat file nested boolean.
 
 757    * @param translateTo  the translate to
 
 758    * @param heatFileName the heat file name
 
 759    * @return the boolean
 
 761   public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
 
 762     return isHeatFileNested(translateTo.getContext(), heatFileName);
 
 765   public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
 
 766     return context.getNestedHeatsFiles().contains(heatFileName);
 
 770    * Extract contrail get resource attached heat resource id optional.
 
 772    * @param propertyValue the property value
 
 773    * @return the optional
 
 775   public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(
 
 776       Object propertyValue) {
 
 777     if (propertyValue instanceof Map) {
 
 778       if (((Map) propertyValue).containsKey(GET_ATTR)) {
 
 779         return getResourceId(((Map) propertyValue).get(GET_ATTR));
 
 780       } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
 
 781         return getHeatResourceIdFromResource((Map) propertyValue);
 
 783         Collection valCollection = ((Map) propertyValue).values();
 
 784         return evaluateHeatResourceId(valCollection);
 
 786     } else if (propertyValue instanceof List) {
 
 787       return evaluateHeatResourceId((List) propertyValue);
 
 789     return Optional.empty();
 
 792   private static Optional<String> getResourceId(Object data) {
 
 793     if (data instanceof List && CollectionUtils.size(data) > 1
 
 794         && FQ_NAME.equals(((List) data).get(1))
 
 795         && ((List) data).get(0) instanceof String) {
 
 796       return Optional.of((String) ((List) data).get(0));
 
 798       LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
 
 799       return Optional.empty();
 
 803   private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
 
 804     Object value = propertyValue.get(GET_RESOURCE);
 
 805     if (value instanceof String) {
 
 806       return Optional.of((String) value);
 
 808       LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
 
 809       return Optional.empty();
 
 813   private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
 
 814     for (Object prop : propertyValue) {
 
 815       Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
 
 816       if (ret.isPresent()) {
 
 820     return Optional.empty();
 
 823    * Gets tosca service model.
 
 825    * @param context translation context
 
 826    * @return the tosca service model
 
 828   public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
 
 829     Map<String, String> metadata = new HashMap<>();
 
 830     metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
 
 831     return getToscaServiceModel(context, metadata);
 
 835    * Gets tosca service model.
 
 837    * @param context                 translation context
 
 838    * @param entryDefinitionMetadata template name of the entry definition servie template
 
 839    * @return the tosca service model
 
 841   public static ToscaServiceModel getToscaServiceModel(
 
 842       TranslationContext context,
 
 843       Map<String, String> entryDefinitionMetadata) {
 
 844     Map<String, ServiceTemplate> serviceTemplates =
 
 845         new HashMap<>(context.getGlobalServiceTemplates());
 
 846     Collection<ServiceTemplate> tmpServiceTemplates =
 
 847         context.getTranslatedServiceTemplates().values();
 
 848     for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
 
 849       ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
 
 851     return new ToscaServiceModel(null, serviceTemplates,
 
 852         ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
 
 856    * Gets service template from context.
 
 858    * @param serviceTemplateFileName the service template file name
 
 859    * @param context                 the context
 
 860    * @return the service template from context
 
 862   public static Optional<ServiceTemplate> getServiceTemplateFromContext(
 
 863       String serviceTemplateFileName, TranslationContext context) {
 
 864     for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
 
 865       if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
 
 866         return Optional.of(serviceTemplate);
 
 869     return Optional.empty();
 
 873    * Adding link requerment from port node template to network node template.
 
 875    * @param portNodeTemplate    port node template
 
 876    * @param networkTranslatedId network node template id
 
 878   public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
 
 879                                                                   String networkTranslatedId) {
 
 880     RequirementAssignment requirement = new RequirementAssignment();
 
 881     requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
 
 882     requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
 
 883     requirement.setNode(networkTranslatedId);
 
 884     DataModelUtil.addRequirementAssignment(portNodeTemplate,
 
 885         ToscaConstants.LINK_REQUIREMENT_ID, requirement);
 
 890    * Adding binding requerment from sub interface node template to interface (port) node template.
 
 892    * @param subInterfaceNodeTemplate sub interface template
 
 893    * @param interfaceTranslatedId    interface node template id
 
 895   public static void addBindingReqFromSubInterfaceToInterface(
 
 896       NodeTemplate subInterfaceNodeTemplate, String interfaceTranslatedId) {
 
 897     RequirementAssignment requirement = new RequirementAssignment();
 
 898     requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
 
 899     requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
 
 900     requirement.setNode(interfaceTranslatedId);
 
 902         .addRequirementAssignment(subInterfaceNodeTemplate,
 
 903             ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
 
 907    * Get property Parameter Name Value.
 
 909    * @param property property
 
 910    * @return Parameter name in case the property include "get_param" function
 
 912   public static Optional<String> getPropertyParameterNameValue(Object property) {
 
 913     if (Objects.isNull(property)) {
 
 914       return Optional.empty();
 
 916     Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
 
 917     if (extractedProperty.isPresent()) {
 
 918       return getParameterName(extractedProperty.get());
 
 920     return Optional.empty();
 
 923   private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
 
 924     if (!extractedProperty.isGetParam()) {
 
 925       return Optional.empty();
 
 927     Object getParamFuncValue = extractedProperty.getPropertyValue();
 
 928     if (getParamFuncValue instanceof String) {
 
 929       return Optional.of((String) getParamFuncValue);
 
 931       return Optional.of((String) ((List) getParamFuncValue).get(0));
 
 935   public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
 
 936                                             String heatPropertyName) {
 
 937     return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
 
 941    * Gets tosca property name.
 
 943    * @param translateTo      the translate to
 
 944    * @param heatPropertyName the heat property name
 
 945    * @return the tosca property name
 
 947   public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
 
 948     return translateTo.getContext()
 
 949         .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
 
 953    * Gets tosca attribute name.
 
 955    * @param context          the context
 
 956    * @param heatResourceType the heat resource type
 
 957    * @param heatAttrName     the heat attr name
 
 958    * @return the tosca attribute name
 
 960   public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
 
 961                                              String heatAttrName) {
 
 962     return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
 
 966    * Gets tosca attribute name.
 
 968    * @param translateTo  the translate to
 
 969    * @param heatAttrName the heat attr name
 
 970    * @return the tosca attribute name
 
 972   public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
 
 973     return translateTo.getContext()
 
 974         .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
 
 978    * Create init substitution service template service template.
 
 980    * @param templateName the template name
 
 981    * @return the service template
 
 983   public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
 
 984     ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
 
 985     Map<String, String> templateMetadata = new HashMap<>();
 
 986     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
 
 987     nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
 
 988     nestedSubstitutionServiceTemplate
 
 989         .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
 
 990     nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
 
 991     List<Map<String, Import>> globalTypesImportList =
 
 992         GlobalTypesGenerator.getGlobalTypesImportList();
 
 993     globalTypesImportList.addAll(
 
 994         HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
 
 995     nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
 
 996     return nestedSubstitutionServiceTemplate;
 
1000    * Create init global substitution service template service template.
 
1002    * @return the service template
 
1004   public static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
 
1005     ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
 
1006     Map<String, String> templateMetadata = new HashMap<>();
 
1007     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
 
1008         Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
 
1009     globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
 
1010     globalSubstitutionServiceTemplate
 
1011         .setImports(GlobalTypesGenerator.getGlobalTypesImportList());
 
1012     globalSubstitutionServiceTemplate
 
1013         .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
 
1014     return globalSubstitutionServiceTemplate;
 
1018    * Create substitution node type node type.
 
1020    * @param substitutionServiceTemplate the substitution service template
 
1021    * @return the node type
 
1023   public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
 
1024     NodeType substitutionNodeType = new NodeType();
 
1025     substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
 
1026     substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
 
1027     substitutionNodeType
 
1028         .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
 
1029     substitutionNodeType
 
1030         .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
 
1031     return substitutionNodeType;
 
1034   private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
 
1035       ServiceTemplate substitutionServiceTemplate) {
 
1036     Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
 
1037     Map<String, ParameterDefinition> properties =
 
1038         substitutionServiceTemplate.getTopology_template().getInputs();
 
1039     if (properties == null) {
 
1043     PropertyDefinition propertyDefinition;
 
1044     String toscaPropertyName;
 
1045     for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
 
1046       toscaPropertyName = entry.getKey();
 
1047       propertyDefinition = new PropertyDefinition();
 
1048       ParameterDefinition parameterDefinition =
 
1049           substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
 
1050       propertyDefinition.setType(parameterDefinition.getType());
 
1051       propertyDefinition.setDescription(parameterDefinition.getDescription());
 
1052       propertyDefinition.setRequired(parameterDefinition.getRequired());
 
1053       propertyDefinition.set_default(parameterDefinition.get_default());
 
1054       propertyDefinition.setConstraints(parameterDefinition.getConstraints());
 
1055       propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
 
1056       propertyDefinition.setStatus(parameterDefinition.getStatus());
 
1057       substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
 
1059     return substitutionNodeTypeProperties;
 
1062   private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
 
1063       ServiceTemplate substitutionServiceTemplate) {
 
1064     Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
 
1065     Map<String, ParameterDefinition> attributes =
 
1066         substitutionServiceTemplate.getTopology_template().getOutputs();
 
1067     if (attributes == null) {
 
1070     AttributeDefinition attributeDefinition;
 
1071     String toscaAttributeName;
 
1073     for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
 
1074       attributeDefinition = new AttributeDefinition();
 
1075       toscaAttributeName = entry.getKey();
 
1076       ParameterDefinition parameterDefinition =
 
1077           substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
 
1078       if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
 
1079         attributeDefinition.setType(parameterDefinition.getType());
 
1081         attributeDefinition.setType(PropertyType.STRING.getDisplayName());
 
1083       attributeDefinition.setDescription(parameterDefinition.getDescription());
 
1084       attributeDefinition.set_default(parameterDefinition.get_default());
 
1085       attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
 
1086       attributeDefinition.setStatus(parameterDefinition.getStatus());
 
1087       substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
 
1089     return substitutionNodeTypeAttributes;
 
1094    * Create and add substitution mapping to the nested substitution service template, and update
 
1095    * the subtitution node type accordingly with the exposed requerments and capabilities
 
1097    * @param context                           the translation context
 
1098    * @param substitutionNodeTypeKey           the substitution node type key
 
1099    * @param nestedSubstitutionServiceTemplate the nested substitution service template
 
1100    * @param substitutionNodeType              the substitution node type
 
1102   public static void handleSubstitutionMapping(
 
1103       TranslationContext context,
 
1104       String substitutionNodeTypeKey,
 
1105       ServiceTemplate nestedSubstitutionServiceTemplate,
 
1106       NodeType substitutionNodeType) {
 
1107     Map<String, Map<String, List<String>>> substitutionMapping =
 
1108         getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
 
1109             nestedSubstitutionServiceTemplate, context);
 
1110     //add substitution mapping after capability and requirement expose calculation
 
1111     nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
 
1112         DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeKey,
 
1113             substitutionNodeType, substitutionMapping));
 
1117    * Gets node type with flat hierarchy.
 
1119    * @param nodeTypeId      the node type id
 
1120    * @param serviceTemplate the service template
 
1121    * @param context         the context
 
1122    * @return the node type with flat hierarchy
 
1124   public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId,
 
1125                                                       ServiceTemplate serviceTemplate,
 
1126                                                       TranslationContext context) {
 
1127     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
 
1128     ToscaServiceModel toscaServiceModel = HeatToToscaUtil
 
1129         .getToscaServiceModel(context, serviceTemplate.getMetadata());
 
1130     return (NodeType) toscaAnalyzerService
 
1131         .getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate, toscaServiceModel);
 
1135    * Create substitution node template node template.
 
1137    * @param translateTo             the translate to
 
1138    * @param templateName            the template name
 
1139    * @param substitutionNodeTypeKey the substitution node type key
 
1140    * @return the node template
 
1142   public NodeTemplate createSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
 
1143                                                      String substitutionNodeTypeKey) {
 
1144     NodeTemplate substitutionNodeTemplate = new NodeTemplate();
 
1145     List<String> directiveList = new ArrayList<>();
 
1146     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
 
1147     substitutionNodeTemplate.setDirectives(directiveList);
 
1148     substitutionNodeTemplate.setType(substitutionNodeTypeKey);
 
1149     substitutionNodeTemplate.setProperties(
 
1150         managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
 
1152     return substitutionNodeTemplate;
 
1156    * Create abstract substitution node template.
 
1158    * @param translateTo             the translate to
 
1159    * @param templateName            the template name
 
1160    * @param substitutionNodeTypeKey the substitution node type key
 
1161    * @return the abstract substitute node template
 
1163   public static NodeTemplate createAbstractSubstitutionNodeTemplate(
 
1164       TranslateTo translateTo,
 
1165       String templateName,
 
1166       String substitutionNodeTypeKey) {
 
1167     NodeTemplate substitutionNodeTemplate = new NodeTemplate();
 
1168     List<String> directiveList = new ArrayList<>();
 
1169     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
 
1170     substitutionNodeTemplate.setDirectives(directiveList);
 
1171     substitutionNodeTemplate.setType(substitutionNodeTypeKey);
 
1172     substitutionNodeTemplate.setProperties(
 
1173         managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
 
1175     return substitutionNodeTemplate;
 
1180    * Checks if the source and target resource is a valid candidate for adding tosca dependency
 
1183    * @param sourceResource          the source resource
 
1184    * @param targetResource          the target resource
 
1185    * @param dependencyEntity        the dependency entity
 
1186    * @return true if the candidate resources are a valid combination for the dependency relationship
 
1187    *              and false otherwise
 
1189   public static boolean isValidDependsOnCandidate(Resource sourceResource,
 
1190                                                   Resource targetResource,
 
1191                                                   ConsolidationEntityType dependencyEntity,
 
1192                                                   TranslationContext context) {
 
1193     dependencyEntity.setEntityType(sourceResource, targetResource, context);
 
1194     ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
 
1195     ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
 
1197     return ConsolidationTypesConnectivity
 
1198         .isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
 
1201   private static Map<String, Object> managerSubstitutionNodeTemplateProperties(
 
1202       TranslateTo translateTo,
 
1204       String templateName) {
 
1205     Map<String, Object> substitutionProperties = new HashMap<>();
 
1206     Map<String, Object> heatProperties = translateTo.getResource().getProperties();
 
1207     if (Objects.nonNull(heatProperties)) {
 
1208       for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
 
1209         Object property = TranslatorHeatToToscaPropertyConverter
 
1210             .getToscaPropertyValue(translateTo.getServiceTemplate(),
 
1211                 translateTo.getTranslatedId(), entry.getKey(),
 
1212                 entry.getValue(), null, translateTo.getHeatFileName(),
 
1213                 translateTo.getHeatOrchestrationTemplate(), template, translateTo.getContext());
 
1214         substitutionProperties.put(entry.getKey(), property);
 
1217     return addAbstractSubstitutionProperty(templateName, substitutionProperties);
 
1220   private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
 
1222                                                                          substitutionProperties) {
 
1223     Map<String, Object> innerProps = new HashMap<>();
 
1224     innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
 
1225         ToscaUtil.getServiceTemplateFileName(templateName));
 
1226     substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
 
1227     return substitutionProperties;
 
1230   private static Map<String, Map<String, List<String>>>
 
1231   getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
 
1232                                                  ServiceTemplate substitutionServiceTemplate,
 
1233                                                  TranslationContext context) {
 
1234     Map<String, NodeTemplate> nodeTemplates =
 
1235         substitutionServiceTemplate.getTopology_template().getNode_templates();
 
1236     String nodeTemplateId;
 
1237     NodeTemplate nodeTemplate;
 
1239     Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
 
1240     if (nodeTemplates == null) {
 
1241       return substitutionMapping;
 
1244     Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
 
1245     Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
 
1246     substitutionMapping.put("capability", capabilitySubstitutionMapping);
 
1247     substitutionMapping.put("requirement", requirementSubstitutionMapping);
 
1248     List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
 
1249     Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
 
1250     List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
 
1251     Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition =
 
1253     Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
 
1254     Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
 
1255     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
 
1257     for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
 
1258       nodeTemplateId = entry.getKey();
 
1259       nodeTemplate = entry.getValue();
 
1260       nodeType = nodeTemplate.getType();
 
1263       nodeTypeRequirementsDefinition =
 
1264           getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
 
1265               requirementSubstitutionMapping, context);
 
1266       nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
 
1267       fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
 
1268       //set substitution node type requirements
 
1269       exposedRequirementsDefinition =
 
1270           toscaAnalyzerService.calculateExposedRequirements(nodeTypeRequirementsDefinition,
 
1271               nodeTemplateRequirementsAssignment);
 
1273           .addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
 
1277       addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition,
 
1278           capabilitySubstitutionMapping, nodeType,
 
1279           nodeTemplateId, substitutionServiceTemplate, context);
 
1282     exposedCapabilitiesDefinition =
 
1283         toscaAnalyzerService.calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
 
1284             fullFilledRequirementsDefinition);
 
1285     DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
 
1286     return substitutionMapping;
 
1289   private static void addNodeTypeCapabilitiesToSubMapping(
 
1290       Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
 
1291       Map<String, List<String>> capabilitySubstitutionMapping, String type, String templateName,
 
1292       ServiceTemplate serviceTemplate, TranslationContext context) {
 
1293     NodeType flatNodeType =
 
1294         getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
 
1296     if (flatNodeType.getCapabilities() != null) {
 
1297       flatNodeType.getCapabilities()
 
1300           .forEach(capabilityNodeEntry ->
 
1301               addCapabilityToSubMapping(
 
1302                   templateName, capabilityNodeEntry, nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping));
 
1306   public static boolean shouldAnnotationsToBeAdded() {
 
1307     return ToggleableFeature.ANNOTATIONS.isActive();
 
1310   private static void addCapabilityToSubMapping(String templateName,
 
1311                                                 Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
 
1312                                                 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
 
1313                                                 Map<String, List<String>> capabilitySubstitutionMapping) {
 
1314     String capabilityKey;
 
1315     List<String> capabilityMapping;
 
1316     capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
 
1317     nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
 
1318     capabilityMapping = new ArrayList<>();
 
1319     capabilityMapping.add(templateName);
 
1320     capabilityMapping.add(capabilityNodeEntry.getKey());
 
1321     capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
 
1324   private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(
 
1326       String templateName,
 
1327       ServiceTemplate serviceTemplate,
 
1328       Map<String, List<String>> requirementSubstitutionMapping,
 
1329       TranslationContext context) {
 
1330     List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
 
1331     NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
 
1332     List<String> requirementMapping;
 
1334     if (flatNodeType.getRequirements() == null) {
 
1335       return requirementList;
 
1338     for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
 
1339       for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap
 
1341         ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
 
1342         RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil
 
1343             .yamlToObject(toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
 
1344                 RequirementDefinition.class);
 
1345         if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
 
1346           requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
 
1348         Map<String, RequirementDefinition> requirementDef = new HashMap<>();
 
1349         requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
 
1350         DataModelUtil.addRequirementToList(requirementList, requirementDef);
 
1351         requirementMapping = new ArrayList<>();
 
1352         requirementMapping.add(templateName);
 
1353         requirementMapping.add(requirementNodeEntry.getKey());
 
1354         requirementSubstitutionMapping
 
1355             .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
 
1356         if (Objects.isNull(requirementNodeEntryValue.getNode())) {
 
1357           requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
 
1361     return requirementList;
 
1365    * Fetch global substitution service template service template.
 
1367    * @param serviceTemplate the service template
 
1368    * @param context         the context
 
1369    * @return the service template
 
1371   public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(
 
1372       ServiceTemplate serviceTemplate,
 
1373       TranslationContext context) {
 
1374     ServiceTemplate globalSubstitutionServiceTemplate =
 
1375         context.getTranslatedServiceTemplates()
 
1376             .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
 
1377     if (globalSubstitutionServiceTemplate == null) {
 
1378       globalSubstitutionServiceTemplate =
 
1379           HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
 
1380       context.getTranslatedServiceTemplates()
 
1381           .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
 
1382               globalSubstitutionServiceTemplate);
 
1384     boolean isImportAddedToServiceTemplate =
 
1385         DataModelUtil.isImportAddedToServiceTemplate(serviceTemplate.getImports(), Constants
 
1386             .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
 
1387     if (!isImportAddedToServiceTemplate) {
 
1388       serviceTemplate.getImports()
 
1390               HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
 
1392     return globalSubstitutionServiceTemplate;
 
1395   public static List<Map<String, Import>> createImportList(String templateName) {
 
1396     List<Map<String, Import>> imports = new ArrayList<>();
 
1397     Map<String, Import> importsMap = new HashMap<>();
 
1398     importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
 
1399     imports.add(importsMap);
 
1404    * Create service template import import.
 
1406    * @param serviceTemplate the service template
 
1407    * @return the import
 
1409   public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
 
1410     Import serviceTemplateImport = new Import();
 
1411     serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
 
1412     return serviceTemplateImport;
 
1416    * Create service template import import.
 
1418    * @param metadataTemplateName the service template name
 
1419    * @return the import
 
1421   public static Import createServiceTemplateImport(String metadataTemplateName) {
 
1422     Import serviceTemplateImport = new Import();
 
1423     serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
 
1424     return serviceTemplateImport;
 
1427   public static ToscaServiceModel createToscaServiceModel(ServiceTemplate
 
1428                                                               entryDefinitionServiceTemplate,
 
1429                                                           TranslationContext translationContext) {
 
1430     return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
 
1431         getServiceTemplates(translationContext),
 
1432         ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
 
1435   private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
 
1436     FileContentHandler artifactFiles = new FileContentHandler();
 
1437     artifactFiles.setFiles(translationContext.getFiles());
 
1438     artifactFiles.setFiles(translationContext.getExternalArtifacts());
 
1440     HeatTreeManager heatTreeManager =
 
1441         HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
 
1442     heatTreeManager.createTree();
 
1443     ValidationStructureList validationStructureList =
 
1444         new ValidationStructureList(heatTreeManager.getTree());
 
1445     byte[] validationStructureFile =
 
1446         FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
 
1447     artifactFiles.addFile("HEAT.meta", validationStructureFile);
 
1448     return artifactFiles;
 
1452   private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext
 
1453                                                                       translationContext) {
 
1454     List<ServiceTemplate> serviceTemplates = new ArrayList<>();
 
1455     serviceTemplates.addAll(GlobalTypesGenerator
 
1456         .getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
 
1457     serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
 
1458     Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
 
1460     for (ServiceTemplate template : serviceTemplates) {
 
1461       serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
 
1463     return serviceTemplatesMap;
 
1466   public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
 
1467     String nestedFileName = translateTo.getResource().getType();
 
1468     if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext())
 
1469         && isSubInterfaceBoundToPort(translateTo)) {
 
1470       return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
 
1472     return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
 
1475   private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
 
1476     return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
 
1479   //Method evaluate the  network role from sub interface node template id, designed considering
 
1480   // only single sub interface present in nested file else it will return null
 
1481   public static Optional<String> getNetworkRoleFromResource(Resource resource,
 
1482                                                             TranslationContext translationContext) {
 
1483     Optional<String> networkRole = Optional.empty();
 
1484     Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
 
1486     if (!nestedHeatFileName.isPresent()) {
 
1490     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
1491         .yamlToObject(translationContext.getFileContent(nestedHeatFileName.get()),
 
1492             HeatOrchestrationTemplate.class);
 
1494     if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
 
1495       ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
 
1496           new ContrailV2VirtualMachineInterfaceHelper();
 
1497       Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource = nestedHeatOrchestrationTemplate
 
1498           .getResources().entrySet().stream()
 
1499           .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
 
1500               .isVlanSubInterfaceResource(resourceEntry.getValue()))
 
1502       if (vlanSubInterfaceResource.isPresent()) {
 
1503         Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
 
1504         networkRole = evaluateNetworkRoleFromResourceId(vlanSubInterfaceResourceEntry.getKey(),
 
1505             vlanSubInterfaceResourceEntry.getValue().getType());
 
1511   public static Optional<String> evaluateNetworkRoleFromResourceId(String resourceId, String resourceType) {
 
1512     if (resourceType.equals(HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
 
1513       return Optional.ofNullable(extractNetworkRoleFromContrailPortId(resourceId));
 
1516     if (resourceType.equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
 
1517       return Optional.ofNullable(extractNetworkRoleFromNeutronPortId(resourceId));
 
1519     return Optional.empty();
 
1522   private static String extractNetworkRoleFromContrailPortId(String portResourceId) {
 
1523     String vmiResourceIdRegex = "(\\w+)(_\\d+){0,1}_(\\w+)_vmi(_\\d+){0,1}";
 
1524     String vmiIntResourceIdRegex = "(\\w+)(_\\d+){0,1}_int_(\\w+)_vmi(_\\d+){0,1}";
 
1526     String portNetworkRole = getPortNetworkRole(portResourceId, vmiResourceIdRegex);
 
1527     String portIntNetworkRole = getPortNetworkRole(portResourceId, vmiIntResourceIdRegex);
 
1529     return Objects.nonNull(portNetworkRole) ? portNetworkRole : portIntNetworkRole;
 
1533   private static String extractNetworkRoleFromNeutronPortId(String portResourceId) {
 
1534     String portResourceIdRegex = "(\\w+)(_\\d+){0,1}_(\\w+)_port(_\\d+){0,1}";
 
1535     String portIntResourceIdRegex = "(\\w+)(_\\d+){0,1}_int_(\\w+)_port(_\\d+){0,1}";
 
1537     String portNetworkRole = getPortNetworkRole(portResourceId, portResourceIdRegex);
 
1538     String portIntNetworkRole = getPortNetworkRole(portResourceId, portIntResourceIdRegex);
 
1540     return Objects.nonNull(portNetworkRole) ? portNetworkRole : portIntNetworkRole;
 
1543   private static String getPortNetworkRole(String portResourceId, String portIdRegex) {
 
1544     Pattern pattern = Pattern.compile(portIdRegex);
 
1545     Matcher matcher = pattern.matcher(portResourceId);
 
1546     if (matcher.matches()) {
 
1547       String networkRole = matcher.group(3);
 
1548       //Assuming network role will not contain ONLY digits
 
1549       if (!networkRole.matches("\\d+")) {
 
1550         return matcher.group(3);