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.onap.sdc.tosca.datatypes.model.AttributeDefinition;
 
  54 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
 
  55 import org.onap.sdc.tosca.datatypes.model.Import;
 
  56 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
 
  57 import org.onap.sdc.tosca.datatypes.model.NodeType;
 
  58 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
 
  59 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
 
  60 import org.onap.sdc.tosca.datatypes.model.PropertyType;
 
  61 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
 
  62 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
 
  63 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
 
  64 import org.onap.sdc.tosca.datatypes.model.Template;
 
  65 import org.onap.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.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
 
  70 import org.openecomp.sdc.tosca.services.ToscaUtil;
 
  71 import org.onap.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   private static final String FQ_NAME = "fq_name";
 
 108   private 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 UNDERSCORE = "_";
 
 112   private static final String WORDS_REGEX = "(\\w+)";
 
 113   private static final String PORT_RESOURCE_ID_REGEX_SUFFIX = "(_\\d+)*";
 
 114   private static final String PORT_RESOURCE_ID_REGEX_PREFIX =
 
 115       WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX;
 
 116   private static final String PORT_INT_RESOURCE_ID_REGEX_PREFIX = PORT_RESOURCE_ID_REGEX_PREFIX
 
 117       + UNDERSCORE + "int_"+ WORDS_REGEX + UNDERSCORE;
 
 118   private static final String SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX =
 
 119       PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + "subint_"+ WORDS_REGEX + UNDERSCORE;
 
 120   private static final String SUB_INTERFACE_REGEX = WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX
 
 121       + "_subint_(\\w_+)*vmi" + PORT_RESOURCE_ID_REGEX_SUFFIX;
 
 124    * Load and translate template data translator output.
 
 126    * @param fileNameContentMap the file name content map
 
 127    * @return the translator output
 
 129   public static TranslatorOutput loadAndTranslateTemplateData(
 
 130       FileContentHandler fileNameContentMap) {
 
 131     HeatToToscaTranslator heatToToscaTranslator =
 
 132         HeatToToscaTranslatorFactory.getInstance().createInterface();
 
 134     try (InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME)) {
 
 135       heatToToscaTranslator
 
 136           .addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
 
 137     } catch (IOException e) {
 
 138       throw new RuntimeException("Failed to read manifest", e);
 
 141     fileNameContentMap.getFileList().stream()
 
 142         .filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME))).forEach(
 
 143         fileName -> heatToToscaTranslator
 
 144             .addFile(fileName, FileUtils.toByteArray
 
 145                 (fileNameContentMap.getFileContent(fileName))));
 
 147     Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
 
 148     if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
 
 149       TranslatorOutput translatorOutput = new TranslatorOutput();
 
 150       translatorOutput.setErrorMessages(errors);
 
 151       return translatorOutput;
 
 154     try (InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap)) {
 
 155       heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
 
 156       return heatToToscaTranslator.translate();
 
 157     } catch (IOException e) {
 
 158       // rethrow as a RuntimeException to keep the signature backward compatible
 
 159       throw new RuntimeException("Failed to read Heat template tree", e);
 
 164   private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
 
 165     HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
 
 166     heatTreeManager.createTree();
 
 167     HeatStructureTree tree = heatTreeManager.getTree();
 
 168     ValidationStructureList validationStructureList = new ValidationStructureList(tree);
 
 169     return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
 
 173    * Build list of files to search optional.
 
 175    * @param heatFileName  the heat file name
 
 176    * @param filesDataList the files data list
 
 177    * @param types         the types
 
 178    * @return the optional
 
 180   public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
 
 181                                                                   List<FileData> filesDataList,
 
 182                                                                   FileData.Type... types) {
 
 183     List<FileData> list = new ArrayList<>(filesDataList);
 
 184     Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
 
 185     if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
 
 186       list.addAll(resourceFileData.get().getData());
 
 188     return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
 
 192    * Gets filtered list of file data by types.
 
 194    * @param filesToSearch the files to search
 
 195    * @param types         the types
 
 196    * @return the filtered list of file data by types
 
 198   public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
 
 199                                                                 FileData.Type... types) {
 
 200     return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types))
 
 201         .collect(Collectors.toList());
 
 205    * Gets file data from the list according to the input heat file name.
 
 207    * @param heatFileName the heat file name
 
 208    * @param fileDataList the file data list
 
 209    * @return the file data
 
 211   public static Optional<FileData> getFileData(String heatFileName,
 
 212                                                Collection<FileData> fileDataList) {
 
 213     for (FileData file : fileDataList) {
 
 214       if (file.getFile().equals(heatFileName)) {
 
 215         return Optional.of(file);
 
 218     return Optional.empty();
 
 222    * Gets file data which is supported by the translator, from the context according the input heat
 
 225    * @param heatFileName the heat file name
 
 226    * @param context      the translation context
 
 227    * @return the file data
 
 229   public static FileData getFileData(String heatFileName, TranslationContext context) {
 
 230     List<FileData> fileDataList = context.getManifest().getContent().getData();
 
 231     for (FileData fileData : fileDataList) {
 
 232       if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType())
 
 233           && fileData.getFile().equals(heatFileName)) {
 
 240   static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList,
 
 241                                                        Set<FileData.Type> typeFilter,
 
 242                                                        TranslationContext translationContext) {
 
 243     FileDataCollection fileDataCollection = new FileDataCollection();
 
 244     Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
 
 245     Set<String> referenced = new HashSet<>();
 
 247     for (FileData fileData : filteredFiles.values()) {
 
 248       String fileName = fileData.getFile();
 
 250       if (FileData.isHeatFile(fileData.getType())) {
 
 251         if (fileData.getBase() != null && fileData.getBase()) {
 
 252           fileDataCollection.addBaseFiles(fileData);
 
 254         HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
 
 255             .yamlToObject(translationContext.getFileContent(fileName),
 
 256                 HeatOrchestrationTemplate.class);
 
 257         if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
 
 258           applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext,
 
 259               fileDataCollection, filteredFiles, referenced);
 
 263         fileDataCollection.addArtifactFiles(fileData);
 
 264         filteredFiles.remove(fileData.getFile());
 
 268     referenced.forEach(filteredFiles::remove);
 
 269     if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
 
 270       for (FileData fileData : fileDataCollection.getBaseFile()) {
 
 271         filteredFiles.remove(fileData.getFile());
 
 274     fileDataCollection.setAddOnFiles(filteredFiles.values());
 
 275     return fileDataCollection;
 
 278   private static void applyFilterOnFileCollection(
 
 279       HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 280       TranslationContext translationContext,
 
 281       FileDataCollection fileDataCollection, Map<String, FileData> filteredFiles,
 
 282       Set<String> referenced) {
 
 283     List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
 
 285     for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
 
 286       if (filenames.contains(resource.getType())) {
 
 287         handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
 
 289       } else if (resource.getType()
 
 290           .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 291         handleResourceGrpNestedFile(resource, translationContext, fileDataCollection,
 
 292             filteredFiles, filenames, referenced);
 
 297   private static void handleResourceGrpNestedFile(Resource resource,
 
 298                                                   TranslationContext translationContext,
 
 299                                                   FileDataCollection fileDataCollection,
 
 300                                                   Map<String, FileData> filteredFiles,
 
 301                                                   List<String> filenames,
 
 302                                                   Set<String> referenced) {
 
 303     Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 304     Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 305     if (innerTypeDef instanceof String) {
 
 306       String internalResourceType = (String) innerTypeDef;
 
 307       if (filenames.contains(internalResourceType)) {
 
 308         handleNestedFile(translationContext, fileDataCollection, filteredFiles,
 
 309             referenced, internalResourceType);
 
 314   private static void handleNestedFile(TranslationContext translationContext,
 
 315                                        FileDataCollection fileDataCollection,
 
 316                                        Map<String, FileData> filteredFiles, Set<String> referenced,
 
 317                                        String nestedFileName) {
 
 318     referenced.add(nestedFileName);
 
 319     fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
 
 320     translationContext.getNestedHeatsFiles().add(nestedFileName);
 
 323   private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
 
 324                                                                 Set<FileData.Type> typesToGet) {
 
 325     Map<String, FileData> filtered = new HashMap<>();
 
 326     fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
 
 327         .forEach(file -> filtered.put(file.getFile(), file));
 
 331   private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
 
 332     return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
 
 336    * Extract attached resource id optional.
 
 338    * @param translateTo  the translate to
 
 339    * @param propertyName the property name
 
 340    * @return the optional
 
 342   public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
 
 343                                                                        String propertyName) {
 
 344     Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
 
 345     if (propertyValue == null) {
 
 346       return Optional.empty();
 
 348     return extractAttachedResourceId(translateTo.getHeatFileName(),
 
 349         translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(), propertyValue);
 
 353    * Extract attached resource id optional.
 
 355    * @param heatFileName              the heat file name
 
 356    * @param heatOrchestrationTemplate the heat orchestration template
 
 357    * @param context                   the context
 
 358    * @param propertyValue             the property value
 
 359    * @return the optional
 
 361   public static Optional<AttachedResourceId> extractAttachedResourceId(
 
 363       HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 364       TranslationContext context,
 
 365       Object propertyValue) {
 
 370     if (Objects.isNull(propertyValue)) {
 
 371       return Optional.empty();
 
 374     ReferenceType referenceType = ReferenceType.OTHER;
 
 375     if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
 
 376       Map<String, Object> propMap = (Map) propertyValue;
 
 377       Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
 
 378       entity = entry.getValue();
 
 379       String key = entry.getKey();
 
 380       referenceType = getReferenceTypeFromAttachedResouce(key);
 
 382       if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
 
 385         translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
 
 386             .translateFunction(null, null, null, entry.getKey(), entry.getValue(), heatFileName,
 
 387                 heatOrchestrationTemplate, null, context);
 
 389       if (translatedId instanceof String
 
 390           && !FunctionTranslationHelper.isResourceSupported((String) translatedId)) {
 
 395       translatedId = propertyValue;
 
 396       entity = propertyValue;
 
 399     return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
 
 402   private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
 
 403     ReferenceType referenceType;
 
 406         referenceType = ReferenceType.GET_RESOURCE;
 
 409         referenceType = ReferenceType.GET_PARAM;
 
 412         referenceType = ReferenceType.GET_ATTR;
 
 415         referenceType = ReferenceType.OTHER;
 
 419     return referenceType;
 
 423    * Gets contrail attached heat resource id.
 
 425    * @param attachedResource the attached resource
 
 426    * @return the contrail attached heat resource id
 
 428   public static Optional<String> getContrailAttachedHeatResourceId(
 
 429       AttachedResourceId attachedResource) {
 
 430     if (attachedResource == null) {
 
 431       return Optional.empty();
 
 434     if (attachedResource.isGetResource()) {
 
 435       return Optional.of((String) attachedResource.getEntityId());
 
 438     if (attachedResource.isGetAttr()) {
 
 439       return getResourceId(attachedResource.getEntityId());
 
 441     return Optional.empty();
 
 445    * Extract property optional.
 
 447    * @param propertyValue the property value
 
 448    * @return the optional
 
 450   private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
 
 451     Object attachedPropertyVal;
 
 452     if (Objects.isNull(propertyValue)) {
 
 453       return Optional.empty();
 
 456     ReferenceType referenceType = ReferenceType.OTHER;
 
 457     if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
 
 458       Map<String, Object> propMap = (Map) propertyValue;
 
 459       Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
 
 460       attachedPropertyVal = entry.getValue();
 
 461       String key = entry.getKey();
 
 464           referenceType = ReferenceType.GET_RESOURCE;
 
 467           referenceType = ReferenceType.GET_PARAM;
 
 470           referenceType = ReferenceType.GET_ATTR;
 
 477       attachedPropertyVal = propertyValue;
 
 479     return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
 
 485    * @param nodeTemplate the node template
 
 486    * @param propertyKey  the property key
 
 488   public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
 
 489     Object value = nodeTemplate.getProperties().get(propertyKey);
 
 490     if (value != null && !(value instanceof Map)) {
 
 491       nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
 
 498    * @param nodeTemplate    the node template
 
 499    * @param propertyListKey the property list key
 
 501   public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
 
 502     Object listValue = nodeTemplate.getProperties().get(propertyListKey);
 
 503     if (listValue instanceof List) {
 
 504       List booleanList = (List) listValue;
 
 505       for (int i = 0; i < booleanList.size(); i++) {
 
 506         Object value = booleanList.get(i);
 
 507         if (value != null && !(value instanceof Map)) {
 
 508           booleanList.set(i, HeatBoolean.eval(value));
 
 516    * Is yml file type boolean.
 
 518    * @param filename the filename
 
 519    * @return the boolean
 
 521   public static boolean isYmlFileType(String filename) {
 
 522     String extension = FilenameUtils.getExtension(filename);
 
 523     return "yaml".equalsIgnoreCase(extension)
 
 524         || "yml".equalsIgnoreCase(extension);
 
 528    * Is nested resource boolean.
 
 530    * @param resource the resource
 
 531    * @return the boolean
 
 533   public static boolean isNestedResource(Resource resource) {
 
 534     String resourceType = resource.getType();
 
 536     if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 537       Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 538       if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof
 
 540         //currently only resource group which is poinitng to nested heat file is supported
 
 541         //dynamic type is currently not supported
 
 544       String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
 
 545           .RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 546       if (isYamlFile(internalResourceType)) {
 
 549     } else if (isYamlFile(resourceType)) {
 
 556    * Checks if the current HEAT resource if of type sub interface.
 
 558    * @param resource the resource
 
 559    * @return true if the resource is of sub interface type and false otherwise
 
 561   public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
 
 562     if (!ToggleableFeature.VLAN_TAGGING.isActive()) {
 
 563       //Remove this once feature is stable and moved to production
 
 566     //Check if resource group is a nested resource
 
 567     if (!isNestedResource(resource)) {
 
 570     Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
 
 571     return nestedHeatFileName.filter(fileName ->
 
 572         isNestedVlanResource(fileName, context)).isPresent();
 
 575   private static boolean isNestedVlanResource(String nestedHeatFileName,
 
 576                                               TranslationContext translationContext) {
 
 577     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
 578         .yamlToObject(translationContext.getFileContent(nestedHeatFileName),
 
 579             HeatOrchestrationTemplate.class);
 
 580     return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())
 
 581         && nestedHeatOrchestrationTemplate.getResources().values().stream()
 
 582         .anyMatch(new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
 
 585   public static Optional<String> getSubInterfaceParentPortNodeTemplateId(
 
 586       TranslateTo subInterfaceTo) {
 
 587     String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
 
 588     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
 589         .yamlToObject(subInterfaceTo.getContext().getFileContent(subInterfaceResourceType),
 
 590             HeatOrchestrationTemplate.class);
 
 591     if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
 
 592       return Optional.empty();
 
 594     for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate
 
 595         .getResources().entrySet()) {
 
 596       Resource resource = resourceEntry.getValue();
 
 597       if (isVmiRefsPropertyExists(resource)) {
 
 598         Object toscaPropertyValue =
 
 599             TranslatorHeatToToscaPropertyConverter
 
 600                 .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
 
 601                     resourceEntry.getKey(), HeatConstants.VMI_REFS_PROPERTY_NAME,
 
 602                     resource.getProperties().get(HeatConstants.VMI_REFS_PROPERTY_NAME),
 
 603                     resource.getType(), subInterfaceResourceType, nestedHeatOrchestrationTemplate,
 
 604                     null, subInterfaceTo.getContext());
 
 605         return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
 
 608     return Optional.empty();
 
 611   private static boolean isVmiRefsPropertyExists(Resource resource) {
 
 612     return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
 
 613         .getHeatResource().equals(resource.getType())
 
 614         && MapUtils.isNotEmpty(resource.getProperties())
 
 615         && resource.getProperties().containsKey(HeatConstants.VMI_REFS_PROPERTY_NAME);
 
 618   public static String getSubInterfaceResourceType(Resource resource) {
 
 619     if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
 
 620       return ((Map) resource.getProperties()
 
 621           .get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
 
 622           .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME)
 
 625     return resource.getType();
 
 628   private static Optional<String> getParentNodeTemplateIdFromPropertyValue(
 
 629       Object toscaPropertyValue,
 
 630       TranslateTo subInterfaceTo) {
 
 631     if (toscaPropertyValue instanceof List
 
 632         && ((List) toscaPropertyValue).get(0) instanceof Map) {
 
 633       Resource subInterfaceResource = subInterfaceTo.getResource();
 
 634       Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
 
 635       String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT
 
 637       Map<String, Object> resourceDefPropertiesMap;
 
 638       if (!isYamlFile(subInterfaceResource.getType())) {
 
 639         resourceDefPropertiesMap = (Map) ((Map) subInterfaceResource
 
 640             .getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
 
 641             .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
 
 643         resourceDefPropertiesMap = subInterfaceResource.getProperties();
 
 645       Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
 
 646       if (parentPortObj instanceof Map) {
 
 647         Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
 
 648         if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions
 
 649             .GET_RESOURCE.getFunction())) {
 
 650           return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
 
 651               subInterfaceTo.getHeatOrchestrationTemplate(),
 
 652               parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
 
 653               subInterfaceTo.getContext());
 
 657     return Optional.empty();
 
 661    * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
 
 662    * least one or more compute nodes).
 
 664    * @param resource the resource
 
 665    * @param context  the context
 
 666    * @return true if the resource represents a VFC and false otherwise.
 
 668   public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
 
 669     Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
 
 670     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
 671         .yamlToObject(context.getFileContent(nestedHeatFileName.get()),
 
 672             HeatOrchestrationTemplate.class);
 
 673     if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
 
 674       for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
 
 675         if (ConsolidationDataUtil
 
 676             .isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
 
 685    * Get nested heat file name in case of nested resource.
 
 687    * @param resource the resource
 
 688    * @return the nested heat file name
 
 690   private static Optional<String> getNestedHeatFileName(Resource resource) {
 
 691     if (!isNestedResource(resource)) {
 
 692       return Optional.empty();
 
 695     String resourceType = resource.getType();
 
 697     if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 698       Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 699       String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
 
 700           .RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 701       return Optional.of(internalResourceType);
 
 703     return Optional.of(resourceType);
 
 709    * @param resource the resource
 
 710    * @return the nested file
 
 712   public static Optional<String> getNestedFile(Resource resource) {
 
 713     if (!isNestedResource(resource)) {
 
 714       return Optional.empty();
 
 716     String resourceType = resource.getType();
 
 717     if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
 
 718       Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
 
 719       String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
 
 720           .RESOURCE_DEF_TYPE_PROPERTY_NAME);
 
 721       return Optional.of(internalResourceType);
 
 723       return Optional.of(resourceType);
 
 727   public static boolean isYamlFile(String fileName) {
 
 728     return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
 
 734    * @param heatOrchestrationTemplate the heat orchestration template
 
 735    * @param resourceId                the resource id
 
 736    * @param heatFileName              the heat file name
 
 737    * @return the resource
 
 739   public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 740                                      String resourceId, String heatFileName) {
 
 741     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
 
 742     if (resource == null) {
 
 743       throw new CoreException(
 
 744           new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
 
 753    * @param resourceId                the resource id
 
 754    * @param heatOrchestrationTemplate heat orchestration template
 
 755    * @param heatFileName              heat file name
 
 756    * @return resource type
 
 758   public static String getResourceType(String resourceId,
 
 759                                        HeatOrchestrationTemplate heatOrchestrationTemplate,
 
 760                                        String heatFileName) {
 
 761     return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName)
 
 766    * Is heat file nested boolean.
 
 768    * @param translateTo  the translate to
 
 769    * @param heatFileName the heat file name
 
 770    * @return the boolean
 
 772   public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
 
 773     return isHeatFileNested(translateTo.getContext(), heatFileName);
 
 776   public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
 
 777     return context.getNestedHeatsFiles().contains(heatFileName);
 
 781    * Extract contrail get resource attached heat resource id optional.
 
 783    * @param propertyValue the property value
 
 784    * @return the optional
 
 786   public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(
 
 787       Object propertyValue) {
 
 788     if (propertyValue instanceof Map) {
 
 789       if (((Map) propertyValue).containsKey(GET_ATTR)) {
 
 790         return getResourceId(((Map) propertyValue).get(GET_ATTR));
 
 791       } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
 
 792         return getHeatResourceIdFromResource((Map) propertyValue);
 
 794         Collection valCollection = ((Map) propertyValue).values();
 
 795         return evaluateHeatResourceId(valCollection);
 
 797     } else if (propertyValue instanceof List) {
 
 798       return evaluateHeatResourceId((List) propertyValue);
 
 800     return Optional.empty();
 
 803   private static Optional<String> getResourceId(Object data) {
 
 804     if (data instanceof List && CollectionUtils.size(data) > 1
 
 805         && FQ_NAME.equals(((List) data).get(1))
 
 806         && ((List) data).get(0) instanceof String) {
 
 807       return Optional.of((String) ((List) data).get(0));
 
 809       LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
 
 810       return Optional.empty();
 
 814   private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
 
 815     Object value = propertyValue.get(GET_RESOURCE);
 
 816     if (value instanceof String) {
 
 817       return Optional.of((String) value);
 
 819       LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
 
 820       return Optional.empty();
 
 824   private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
 
 825     for (Object prop : propertyValue) {
 
 826       Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
 
 827       if (ret.isPresent()) {
 
 831     return Optional.empty();
 
 835    * Gets tosca service model.
 
 837    * @param context translation context
 
 838    * @return the tosca service model
 
 840   public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
 
 841     Map<String, String> metadata = new HashMap<>();
 
 842     metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
 
 843     return getToscaServiceModel(context, metadata);
 
 847    * Gets tosca service model.
 
 849    * @param context                 translation context
 
 850    * @param entryDefinitionMetadata template name of the entry definition servie template
 
 851    * @return the tosca service model
 
 853   private static ToscaServiceModel getToscaServiceModel(
 
 854       TranslationContext context,
 
 855       Map<String, String> entryDefinitionMetadata) {
 
 856     Map<String, ServiceTemplate> serviceTemplates =
 
 857         new HashMap<>(context.getGlobalServiceTemplates());
 
 858     Collection<ServiceTemplate> tmpServiceTemplates =
 
 859         context.getTranslatedServiceTemplates().values();
 
 860     for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
 
 861       ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
 
 863     return new ToscaServiceModel(null, serviceTemplates,
 
 864         ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
 
 868    * Gets service template from context.
 
 870    * @param serviceTemplateFileName the service template file name
 
 871    * @param context                 the context
 
 872    * @return the service template from context
 
 874   public static Optional<ServiceTemplate> getServiceTemplateFromContext(
 
 875       String serviceTemplateFileName, TranslationContext context) {
 
 876     for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
 
 877       if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
 
 878         return Optional.of(serviceTemplate);
 
 881     return Optional.empty();
 
 885    * Adding link requerment from port node template to network node template.
 
 887    * @param portNodeTemplate    port node template
 
 888    * @param networkTranslatedId network node template id
 
 890   public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
 
 891                                                                   String networkTranslatedId) {
 
 892     RequirementAssignment requirement = new RequirementAssignment();
 
 893     requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
 
 894     requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
 
 895     requirement.setNode(networkTranslatedId);
 
 896     DataModelUtil.addRequirementAssignment(portNodeTemplate,
 
 897         ToscaConstants.LINK_REQUIREMENT_ID, requirement);
 
 902    * Adding binding requerment from sub interface node template to interface (port) node template.
 
 904    * @param subInterfaceNodeTemplate sub interface template
 
 905    * @param interfaceTranslatedId    interface node template id
 
 907   public static void addBindingReqFromSubInterfaceToInterface(
 
 908       NodeTemplate subInterfaceNodeTemplate, String interfaceTranslatedId) {
 
 909     RequirementAssignment requirement = new RequirementAssignment();
 
 910     requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
 
 911     requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
 
 912     requirement.setNode(interfaceTranslatedId);
 
 914         .addRequirementAssignment(subInterfaceNodeTemplate,
 
 915             ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
 
 919    * Get property Parameter Name Value.
 
 921    * @param property property
 
 922    * @return Parameter name in case the property include "get_param" function
 
 924   public static Optional<String> getPropertyParameterNameValue(Object property) {
 
 925     if (Objects.isNull(property)) {
 
 926       return Optional.empty();
 
 928     Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
 
 929     if (extractedProperty.isPresent()) {
 
 930       return getParameterName(extractedProperty.get());
 
 932     return Optional.empty();
 
 935   private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
 
 936     if (!extractedProperty.isGetParam()) {
 
 937       return Optional.empty();
 
 939     Object getParamFuncValue = extractedProperty.getPropertyValue();
 
 940     if (getParamFuncValue instanceof String) {
 
 941       return Optional.of((String) getParamFuncValue);
 
 943       return Optional.of((String) ((List) getParamFuncValue).get(0));
 
 947   public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
 
 948                                             String heatPropertyName) {
 
 949     return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
 
 953    * Gets tosca property name.
 
 955    * @param translateTo      the translate to
 
 956    * @param heatPropertyName the heat property name
 
 957    * @return the tosca property name
 
 959   public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
 
 960     return translateTo.getContext()
 
 961         .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
 
 965    * Gets tosca attribute name.
 
 967    * @param context          the context
 
 968    * @param heatResourceType the heat resource type
 
 969    * @param heatAttrName     the heat attr name
 
 970    * @return the tosca attribute name
 
 972   public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
 
 973                                              String heatAttrName) {
 
 974     return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
 
 978    * Gets tosca attribute name.
 
 980    * @param translateTo  the translate to
 
 981    * @param heatAttrName the heat attr name
 
 982    * @return the tosca attribute name
 
 984   public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
 
 985     return translateTo.getContext()
 
 986         .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
 
 990    * Create init substitution service template service template.
 
 992    * @param templateName the template name
 
 993    * @return the service template
 
 995   public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
 
 996     ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
 
 997     Map<String, String> templateMetadata = new HashMap<>();
 
 998     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
 
 999     nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
 
1000     nestedSubstitutionServiceTemplate
 
1001         .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
 
1002     nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
 
1003     List<Map<String, Import>> globalTypesImportList =
 
1004         GlobalTypesGenerator.getGlobalTypesImportList();
 
1005     globalTypesImportList.addAll(
 
1006         HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
 
1007     nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
 
1008     return nestedSubstitutionServiceTemplate;
 
1012    * Create init global substitution service template service template.
 
1014    * @return the service template
 
1016   private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
 
1017     ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
 
1018     Map<String, String> templateMetadata = new HashMap<>();
 
1019     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
 
1020         Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
 
1021     globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
 
1022     globalSubstitutionServiceTemplate
 
1023         .setImports(GlobalTypesGenerator.getGlobalTypesImportList());
 
1024     globalSubstitutionServiceTemplate
 
1025         .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
 
1026     return globalSubstitutionServiceTemplate;
 
1030    * Create substitution node type node type.
 
1032    * @param substitutionServiceTemplate the substitution service template
 
1033    * @return the node type
 
1035   public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
 
1036     NodeType substitutionNodeType = new NodeType();
 
1037     substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
 
1038     substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
 
1039     substitutionNodeType
 
1040         .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
 
1041     substitutionNodeType
 
1042         .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
 
1043     return substitutionNodeType;
 
1046   private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
 
1047       ServiceTemplate substitutionServiceTemplate) {
 
1048     Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
 
1049     Map<String, ParameterDefinition> properties =
 
1050         substitutionServiceTemplate.getTopology_template().getInputs();
 
1051     if (properties == null) {
 
1055     PropertyDefinition propertyDefinition;
 
1056     String toscaPropertyName;
 
1057     for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
 
1058       toscaPropertyName = entry.getKey();
 
1059       propertyDefinition = new PropertyDefinition();
 
1060       ParameterDefinition parameterDefinition =
 
1061           substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
 
1062       propertyDefinition.setType(parameterDefinition.getType());
 
1063       propertyDefinition.setDescription(parameterDefinition.getDescription());
 
1064       propertyDefinition.setRequired(parameterDefinition.getRequired());
 
1065       propertyDefinition.set_default(parameterDefinition.get_default());
 
1066       propertyDefinition.setConstraints(parameterDefinition.getConstraints());
 
1067       propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
 
1068       propertyDefinition.setStatus(parameterDefinition.getStatus());
 
1069       substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
 
1071     return substitutionNodeTypeProperties;
 
1074   private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
 
1075       ServiceTemplate substitutionServiceTemplate) {
 
1076     Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
 
1077     Map<String, ParameterDefinition> attributes =
 
1078         substitutionServiceTemplate.getTopology_template().getOutputs();
 
1079     if (attributes == null) {
 
1082     AttributeDefinition attributeDefinition;
 
1083     String toscaAttributeName;
 
1085     for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
 
1086       attributeDefinition = new AttributeDefinition();
 
1087       toscaAttributeName = entry.getKey();
 
1088       ParameterDefinition parameterDefinition =
 
1089           substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
 
1090       if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
 
1091         attributeDefinition.setType(parameterDefinition.getType());
 
1093         attributeDefinition.setType(PropertyType.STRING.getDisplayName());
 
1095       attributeDefinition.setDescription(parameterDefinition.getDescription());
 
1096       attributeDefinition.set_default(parameterDefinition.get_default());
 
1097       attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
 
1098       attributeDefinition.setStatus(parameterDefinition.getStatus());
 
1099       substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
 
1101     return substitutionNodeTypeAttributes;
 
1106    * Create and add substitution mapping to the nested substitution service template, and update
 
1107    * the subtitution node type accordingly with the exposed requerments and capabilities
 
1109    * @param context                           the translation context
 
1110    * @param substitutionNodeTypeKey           the substitution node type key
 
1111    * @param nestedSubstitutionServiceTemplate the nested substitution service template
 
1112    * @param substitutionNodeType              the substitution node type
 
1114   public static void handleSubstitutionMapping(
 
1115       TranslationContext context,
 
1116       String substitutionNodeTypeKey,
 
1117       ServiceTemplate nestedSubstitutionServiceTemplate,
 
1118       NodeType substitutionNodeType) {
 
1119     Map<String, Map<String, List<String>>> substitutionMapping =
 
1120         getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
 
1121             nestedSubstitutionServiceTemplate, context);
 
1122     //add substitution mapping after capability and requirement expose calculation
 
1123     nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
 
1124         DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeKey,
 
1125             substitutionNodeType, substitutionMapping));
 
1129    * Gets node type with flat hierarchy.
 
1131    * @param nodeTypeId      the node type id
 
1132    * @param serviceTemplate the service template
 
1133    * @param context         the context
 
1134    * @return the node type with flat hierarchy
 
1136   public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId,
 
1137                                                       ServiceTemplate serviceTemplate,
 
1138                                                       TranslationContext context) {
 
1139     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
 
1140     ToscaServiceModel toscaServiceModel = HeatToToscaUtil
 
1141         .getToscaServiceModel(context, serviceTemplate.getMetadata());
 
1142     return (NodeType) toscaAnalyzerService
 
1143         .getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate, toscaServiceModel);
 
1147    * Create substitution node template node template.
 
1149    * @param translateTo             the translate to
 
1150    * @param templateName            the template name
 
1151    * @param substitutionNodeTypeKey the substitution node type key
 
1152    * @return the node template
 
1154   public NodeTemplate createSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
 
1155                                                      String substitutionNodeTypeKey) {
 
1156     NodeTemplate substitutionNodeTemplate = new NodeTemplate();
 
1157     List<String> directiveList = new ArrayList<>();
 
1158     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
 
1159     substitutionNodeTemplate.setDirectives(directiveList);
 
1160     substitutionNodeTemplate.setType(substitutionNodeTypeKey);
 
1161     substitutionNodeTemplate.setProperties(
 
1162         managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
 
1164     return substitutionNodeTemplate;
 
1168    * Create abstract substitution node template.
 
1170    * @param translateTo             the translate to
 
1171    * @param templateName            the template name
 
1172    * @param substitutionNodeTypeKey the substitution node type key
 
1173    * @return the abstract substitute node template
 
1175   public static NodeTemplate createAbstractSubstitutionNodeTemplate(
 
1176       TranslateTo translateTo,
 
1177       String templateName,
 
1178       String substitutionNodeTypeKey) {
 
1179     NodeTemplate substitutionNodeTemplate = new NodeTemplate();
 
1180     List<String> directiveList = new ArrayList<>();
 
1181     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
 
1182     substitutionNodeTemplate.setDirectives(directiveList);
 
1183     substitutionNodeTemplate.setType(substitutionNodeTypeKey);
 
1184     substitutionNodeTemplate.setProperties(
 
1185         managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
 
1187     return substitutionNodeTemplate;
 
1192    * Checks if the source and target resource is a valid candidate for adding tosca dependency
 
1195    * @param sourceResource   the source resource
 
1196    * @param targetResource   the target resource
 
1197    * @param dependencyEntity the dependency entity
 
1198    * @return true if the candidate resources are a valid combination for the dependency relationship
 
1199    * and false otherwise
 
1201   public static boolean isValidDependsOnCandidate(Resource sourceResource,
 
1202                                                   Resource targetResource,
 
1203                                                   ConsolidationEntityType dependencyEntity,
 
1204                                                   TranslationContext context) {
 
1205     dependencyEntity.setEntityType(sourceResource, targetResource, context);
 
1206     ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
 
1207     ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
 
1209     return ConsolidationTypesConnectivity
 
1210         .isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
 
1213   private static Map<String, Object> managerSubstitutionNodeTemplateProperties(
 
1214       TranslateTo translateTo,
 
1216       String templateName) {
 
1217     Map<String, Object> substitutionProperties = new HashMap<>();
 
1218     Map<String, Object> heatProperties = translateTo.getResource().getProperties();
 
1219     if (Objects.nonNull(heatProperties)) {
 
1220       for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
 
1221         Object property = TranslatorHeatToToscaPropertyConverter
 
1222             .getToscaPropertyValue(translateTo.getServiceTemplate(),
 
1223                 translateTo.getTranslatedId(), entry.getKey(),
 
1224                 entry.getValue(), null, translateTo.getHeatFileName(),
 
1225                 translateTo.getHeatOrchestrationTemplate(), template, translateTo.getContext());
 
1226         substitutionProperties.put(entry.getKey(), property);
 
1229     return addAbstractSubstitutionProperty(templateName, substitutionProperties);
 
1232   private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
 
1234                                                                          substitutionProperties) {
 
1235     Map<String, Object> innerProps = new HashMap<>();
 
1236     innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
 
1237         ToscaUtil.getServiceTemplateFileName(templateName));
 
1238     substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
 
1239     return substitutionProperties;
 
1242   private static Map<String, Map<String, List<String>>>
 
1243   getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
 
1244                                                  ServiceTemplate substitutionServiceTemplate,
 
1245                                                  TranslationContext context) {
 
1246     Map<String, NodeTemplate> nodeTemplates =
 
1247         substitutionServiceTemplate.getTopology_template().getNode_templates();
 
1248     String nodeTemplateId;
 
1249     NodeTemplate nodeTemplate;
 
1251     Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
 
1252     if (nodeTemplates == null) {
 
1253       return substitutionMapping;
 
1256     Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
 
1257     Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
 
1258     substitutionMapping.put("capability", capabilitySubstitutionMapping);
 
1259     substitutionMapping.put("requirement", requirementSubstitutionMapping);
 
1260     List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
 
1261     Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
 
1262     List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
 
1263     Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition =
 
1265     Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
 
1266     Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
 
1267     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
 
1269     for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
 
1270       nodeTemplateId = entry.getKey();
 
1271       nodeTemplate = entry.getValue();
 
1272       nodeType = nodeTemplate.getType();
 
1275       nodeTypeRequirementsDefinition =
 
1276           getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
 
1277               requirementSubstitutionMapping, context);
 
1278       nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
 
1279       fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
 
1280       //set substitution node type requirements
 
1281       exposedRequirementsDefinition =
 
1282           toscaAnalyzerService.calculateExposedRequirements(nodeTypeRequirementsDefinition,
 
1283               nodeTemplateRequirementsAssignment);
 
1285           .addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
 
1289       addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition,
 
1290           capabilitySubstitutionMapping, nodeType,
 
1291           nodeTemplateId, substitutionServiceTemplate, context);
 
1294     exposedCapabilitiesDefinition =
 
1295         toscaAnalyzerService.calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
 
1296             fullFilledRequirementsDefinition);
 
1297     DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
 
1298     return substitutionMapping;
 
1301   private static void addNodeTypeCapabilitiesToSubMapping(
 
1302       Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
 
1303       Map<String, List<String>> capabilitySubstitutionMapping, String type, String templateName,
 
1304       ServiceTemplate serviceTemplate, TranslationContext context) {
 
1305     NodeType flatNodeType =
 
1306         getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
 
1308     if (flatNodeType.getCapabilities() != null) {
 
1309       flatNodeType.getCapabilities()
 
1312           .forEach(capabilityNodeEntry ->
 
1313               addCapabilityToSubMapping(
 
1314                   templateName, capabilityNodeEntry, nodeTypeCapabilitiesDefinition,
 
1315                   capabilitySubstitutionMapping));
 
1319   public static boolean shouldAnnotationsToBeAdded() {
 
1320     return ToggleableFeature.ANNOTATIONS.isActive();
 
1323   private static void addCapabilityToSubMapping(String templateName,
 
1324                                                 Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
 
1325                                                 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
 
1326                                                 Map<String, List<String>> capabilitySubstitutionMapping) {
 
1327     String capabilityKey;
 
1328     List<String> capabilityMapping;
 
1329     capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
 
1330     nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
 
1331     capabilityMapping = new ArrayList<>();
 
1332     capabilityMapping.add(templateName);
 
1333     capabilityMapping.add(capabilityNodeEntry.getKey());
 
1334     capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
 
1337   private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(
 
1339       String templateName,
 
1340       ServiceTemplate serviceTemplate,
 
1341       Map<String, List<String>> requirementSubstitutionMapping,
 
1342       TranslationContext context) {
 
1343     List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
 
1344     NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
 
1345     List<String> requirementMapping;
 
1347     if (flatNodeType.getRequirements() == null) {
 
1348       return requirementList;
 
1351     for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
 
1352       for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap
 
1354         ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
 
1355         RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil
 
1356             .yamlToObject(toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
 
1357                 RequirementDefinition.class);
 
1358         if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
 
1359           requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
 
1361         Map<String, RequirementDefinition> requirementDef = new HashMap<>();
 
1362         requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
 
1363         DataModelUtil.addRequirementToList(requirementList, requirementDef);
 
1364         requirementMapping = new ArrayList<>();
 
1365         requirementMapping.add(templateName);
 
1366         requirementMapping.add(requirementNodeEntry.getKey());
 
1367         requirementSubstitutionMapping
 
1368             .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
 
1369         if (Objects.isNull(requirementNodeEntryValue.getNode())) {
 
1370           requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
 
1374     return requirementList;
 
1378    * Fetch global substitution service template service template.
 
1380    * @param serviceTemplate the service template
 
1381    * @param context         the context
 
1382    * @return the service template
 
1384   public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(
 
1385       ServiceTemplate serviceTemplate,
 
1386       TranslationContext context) {
 
1387     ServiceTemplate globalSubstitutionServiceTemplate =
 
1388         context.getTranslatedServiceTemplates()
 
1389             .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
 
1390     if (globalSubstitutionServiceTemplate == null) {
 
1391       globalSubstitutionServiceTemplate =
 
1392           HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
 
1393       context.getTranslatedServiceTemplates()
 
1394           .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
 
1395               globalSubstitutionServiceTemplate);
 
1397     boolean isImportAddedToServiceTemplate =
 
1398         DataModelUtil.isImportAddedToServiceTemplate(serviceTemplate.getImports(), Constants
 
1399             .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
 
1400     if (!isImportAddedToServiceTemplate) {
 
1401       serviceTemplate.getImports()
 
1403               HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
 
1405     return globalSubstitutionServiceTemplate;
 
1408   public static List<Map<String, Import>> createImportList(String templateName) {
 
1409     List<Map<String, Import>> imports = new ArrayList<>();
 
1410     Map<String, Import> importsMap = new HashMap<>();
 
1411     importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
 
1412     imports.add(importsMap);
 
1417    * Create service template import import.
 
1419    * @param serviceTemplate the service template
 
1420    * @return the import
 
1422   public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
 
1423     Import serviceTemplateImport = new Import();
 
1424     serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
 
1425     return serviceTemplateImport;
 
1429    * Create service template import import.
 
1431    * @param metadataTemplateName the service template name
 
1432    * @return the import
 
1434   private static Import createServiceTemplateImport(String metadataTemplateName) {
 
1435     Import serviceTemplateImport = new Import();
 
1436     serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
 
1437     return serviceTemplateImport;
 
1440   public static ToscaServiceModel createToscaServiceModel(ServiceTemplate
 
1441                                                               entryDefinitionServiceTemplate,
 
1442                                                           TranslationContext translationContext) {
 
1443     return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
 
1444         getServiceTemplates(translationContext),
 
1445         ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
 
1448   private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
 
1449     FileContentHandler artifactFiles = new FileContentHandler();
 
1450     artifactFiles.setFiles(translationContext.getFiles());
 
1451     artifactFiles.setFiles(translationContext.getExternalArtifacts());
 
1453     HeatTreeManager heatTreeManager =
 
1454         HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
 
1455     heatTreeManager.createTree();
 
1456     ValidationStructureList validationStructureList =
 
1457         new ValidationStructureList(heatTreeManager.getTree());
 
1458     byte[] validationStructureFile =
 
1459         FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
 
1460     artifactFiles.addFile("HEAT.meta", validationStructureFile);
 
1461     return artifactFiles;
 
1465   private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext
 
1466                                                                       translationContext) {
 
1467     List<ServiceTemplate> serviceTemplates = new ArrayList<>();
 
1468     serviceTemplates.addAll(GlobalTypesGenerator
 
1469         .getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
 
1470     serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
 
1471     Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
 
1473     for (ServiceTemplate template : serviceTemplates) {
 
1474       serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
 
1476     return serviceTemplatesMap;
 
1479   public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
 
1480     if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext())
 
1481         && isSubInterfaceBoundToPort(translateTo)) {
 
1482       return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
 
1484     return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
 
1487   private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
 
1488     return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
 
1491   //Method evaluate the  network role from sub interface node template id, designed considering
 
1492   // only single sub interface present in nested file else it will return null
 
1493   public static Optional<String> getNetworkRoleFromSubInterfaceId(Resource resource,
 
1494                                                    TranslationContext translationContext) {
 
1495     Optional<String> networkRole = Optional.empty();
 
1496     Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
 
1498     if (!nestedHeatFileName.isPresent()) {
 
1502     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
 
1503         .yamlToObject(translationContext.getFileContent(nestedHeatFileName.get()),
 
1504             HeatOrchestrationTemplate.class);
 
1506     if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
 
1507       ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
 
1508           new ContrailV2VirtualMachineInterfaceHelper();
 
1509       Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
 
1510           nestedHeatOrchestrationTemplate
 
1511               .getResources().entrySet().stream()
 
1512               .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
 
1513                   .isVlanSubInterfaceResource(resourceEntry.getValue()))
 
1515       if (vlanSubInterfaceResource.isPresent()) {
 
1516         Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
 
1517         networkRole = extractNetworkRoleFromSubInterfaceId(vlanSubInterfaceResourceEntry.getKey(),
 
1518             vlanSubInterfaceResourceEntry.getValue().getType());
 
1524   public static Optional<String> evaluateNetworkRoleFromResourceId(String resourceId,
 
1525                                                                    String resourceType) {
 
1526     Optional<PortType> portType = getPortType(resourceType);
 
1527     if (portType.isPresent()) {
 
1528       String portResourceIdRegex =
 
1529           PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + WORDS_REGEX + UNDERSCORE
 
1530               + portType.get().getPortTypeName() + PORT_RESOURCE_ID_REGEX_SUFFIX;
 
1531       String portIntResourceIdRegex =
 
1532           PORT_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
 
1533               + PORT_RESOURCE_ID_REGEX_SUFFIX;
 
1535       String portNetworkRole = getNetworkRole(resourceId, portResourceIdRegex);
 
1536       String portIntNetworkRole = getNetworkRole(resourceId, portIntResourceIdRegex);
 
1538       return Optional.ofNullable(Objects.nonNull(portNetworkRole)
 
1539           ? portNetworkRole : portIntNetworkRole);
 
1541     return Optional.empty();
 
1544   private static Optional<PortType> getPortType(String resourceType) {
 
1545     if (resourceType.equals(
 
1546         HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
 
1547       return Optional.of(PortType.VMI);
 
1548     } else if (resourceType.equals(
 
1549         HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
 
1550       return Optional.of(PortType.PORT);
 
1552     return Optional.empty();
 
1555   public static Optional<String> extractNetworkRoleFromSubInterfaceId(String  resourceId,
 
1556                                                              String resourceType) {
 
1557     Optional<PortType> portType = getPortType(resourceType);
 
1558     if (portType.isPresent()) {
 
1559       String subInterfaceResourceIdRegex =
 
1560           SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
 
1561               + PORT_RESOURCE_ID_REGEX_SUFFIX;
 
1563       return Optional.ofNullable(getNetworkRole(resourceId, subInterfaceResourceIdRegex));
 
1565     return Optional.empty();
 
1568   private enum PortType {
 
1572     private String portTypeName;
 
1574     PortType(String portTypeName) {
 
1575       this.portTypeName = portTypeName;
 
1578     public String getPortTypeName() {
 
1579       return portTypeName;
 
1583   private static String getNetworkRole(String portResourceId, String portIdRegex) {
 
1584     Pattern pattern = Pattern.compile(portIdRegex);
 
1585     Matcher matcher = pattern.matcher(portResourceId);
 
1586     if (matcher.matches()) {
 
1587       String networkRole = matcher.group(3);
 
1588       //Assuming network role will not contain ONLY digits
 
1589       if (!networkRole.matches("\\d+")) {
 
1590         return matcher.group(3);