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