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 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);