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 static org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator.getFunctionTranslateTo;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
29 import java.util.Objects;
30 import java.util.Optional;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34 import java.util.stream.Collectors;
36 import org.apache.commons.collections4.CollectionUtils;
37 import org.apache.commons.collections4.MapUtils;
38 import org.apache.commons.io.FilenameUtils;
39 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
40 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
41 import org.onap.sdc.tosca.datatypes.model.Import;
42 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
43 import org.onap.sdc.tosca.datatypes.model.NodeType;
44 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
45 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
46 import org.onap.sdc.tosca.datatypes.model.PropertyType;
47 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
48 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
49 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
50 import org.onap.sdc.tosca.datatypes.model.Template;
51 import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
52 import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
53 import org.onap.sdc.tosca.services.YamlUtil;
54 import org.openecomp.core.translator.api.HeatToToscaTranslator;
55 import org.openecomp.core.translator.datatypes.TranslatorOutput;
56 import org.openecomp.core.translator.factory.HeatToToscaTranslatorFactory;
57 import org.openecomp.core.utilities.file.FileContentHandler;
58 import org.openecomp.core.utilities.file.FileUtils;
59 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
60 import org.openecomp.core.validation.util.MessageContainerUtil;
61 import org.openecomp.sdc.common.errors.CoreException;
62 import org.openecomp.sdc.common.togglz.ToggleableFeature;
63 import org.openecomp.sdc.common.utils.SdcCommon;
64 import org.openecomp.sdc.datatypes.error.ErrorLevel;
65 import org.openecomp.sdc.datatypes.error.ErrorMessage;
66 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
67 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
68 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
69 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
70 import org.openecomp.sdc.heat.datatypes.model.Resource;
71 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
72 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
73 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
74 import org.openecomp.sdc.heat.services.HeatConstants;
75 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
76 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
77 import org.openecomp.sdc.logging.api.Logger;
78 import org.openecomp.sdc.logging.api.LoggerFactory;
79 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
80 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
81 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
82 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
83 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
84 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
85 import org.openecomp.sdc.tosca.services.DataModelUtil;
86 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
87 import org.openecomp.sdc.tosca.services.ToscaConstants;
88 import org.openecomp.sdc.tosca.services.ToscaUtil;
89 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
90 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedPropertyVal;
91 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
92 import org.openecomp.sdc.translator.datatypes.heattotosca.ReferenceType;
93 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
94 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
95 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
96 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
97 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
98 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailV2VirtualMachineInterfaceHelper;
99 import org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator;
100 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
101 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
104 * The type Heat to tosca util.
106 public class HeatToToscaUtil {
108 private static final Logger LOGGER = LoggerFactory.getLogger(HeatToToscaUtil.class);
109 private static final String FQ_NAME = "fq_name";
110 private static final String GET_PARAM = "get_param";
111 private static final String GET_ATTR = "get_attr";
112 private static final String GET_RESOURCE = "get_resource";
113 private static final String UNDERSCORE = "_";
114 private static final String WORDS_REGEX = "(\\w+)";
115 private static final String PORT_RESOURCE_ID_REGEX_SUFFIX = "(_\\d+)*";
116 private static final String PORT_RESOURCE_ID_REGEX_PREFIX =
117 WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX;
118 private static final String PORT_INT_RESOURCE_ID_REGEX_PREFIX = PORT_RESOURCE_ID_REGEX_PREFIX
119 + UNDERSCORE + "int_"+ WORDS_REGEX + UNDERSCORE;
120 private static final String SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX =
121 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + "subint_"+ WORDS_REGEX + UNDERSCORE;
122 private static final String SUB_INTERFACE_REGEX = WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX
123 + "_subint_(\\w_+)*vmi" + PORT_RESOURCE_ID_REGEX_SUFFIX;
126 * Load and translate template data translator output.
128 * @param fileNameContentMap the file name content map
129 * @return the translator output
131 public static TranslatorOutput loadAndTranslateTemplateData(
132 FileContentHandler fileNameContentMap) {
133 HeatToToscaTranslator heatToToscaTranslator =
134 HeatToToscaTranslatorFactory.getInstance().createInterface();
136 try (InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME)) {
137 heatToToscaTranslator
138 .addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
139 } catch (IOException e) {
140 throw new RuntimeException("Failed to read manifest", e);
143 fileNameContentMap.getFileList().stream()
144 .filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME))).forEach(
145 fileName -> heatToToscaTranslator
146 .addFile(fileName, FileUtils.toByteArray
147 (fileNameContentMap.getFileContent(fileName))));
149 Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
150 if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
151 TranslatorOutput translatorOutput = new TranslatorOutput();
152 translatorOutput.setErrorMessages(errors);
153 return translatorOutput;
156 try (InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap)) {
157 heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
158 return heatToToscaTranslator.translate();
159 } catch (IOException e) {
160 // rethrow as a RuntimeException to keep the signature backward compatible
161 throw new RuntimeException("Failed to read Heat template tree", e);
166 private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
167 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
168 heatTreeManager.createTree();
169 HeatStructureTree tree = heatTreeManager.getTree();
170 ValidationStructureList validationStructureList = new ValidationStructureList(tree);
171 return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
175 * Build list of files to search optional.
177 * @param heatFileName the heat file name
178 * @param filesDataList the files data list
179 * @param types the types
180 * @return the optional
182 public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
183 List<FileData> filesDataList,
184 FileData.Type... types) {
185 List<FileData> list = new ArrayList<>(filesDataList);
186 Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
187 if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
188 list.addAll(resourceFileData.get().getData());
190 return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
194 * Gets filtered list of file data by types.
196 * @param filesToSearch the files to search
197 * @param types the types
198 * @return the filtered list of file data by types
200 public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
201 FileData.Type... types) {
202 return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types))
203 .collect(Collectors.toList());
207 * Gets file data from the list according to the input heat file name.
209 * @param heatFileName the heat file name
210 * @param fileDataList the file data list
211 * @return the file data
213 public static Optional<FileData> getFileData(String heatFileName,
214 Collection<FileData> fileDataList) {
215 for (FileData file : fileDataList) {
216 if (file.getFile().equals(heatFileName)) {
217 return Optional.of(file);
220 return Optional.empty();
224 * Gets file data which is supported by the translator, from the context according the input heat
227 * @param heatFileName the heat file name
228 * @param context the translation context
229 * @return the file data
231 public static FileData getFileData(String heatFileName, TranslationContext context) {
232 List<FileData> fileDataList = context.getManifest().getContent().getData();
233 for (FileData fileData : fileDataList) {
234 if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType())
235 && fileData.getFile().equals(heatFileName)) {
242 static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList,
243 Set<FileData.Type> typeFilter,
244 TranslationContext translationContext) {
245 FileDataCollection fileDataCollection = new FileDataCollection();
246 Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
247 Set<String> referenced = new HashSet<>();
249 for (FileData fileData : filteredFiles.values()) {
250 String fileName = fileData.getFile();
252 if (FileData.isHeatFile(fileData.getType())) {
253 if (fileData.getBase() != null && fileData.getBase()) {
254 fileDataCollection.addBaseFiles(fileData);
256 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
257 .yamlToObject(translationContext.getFileContent(fileName),
258 HeatOrchestrationTemplate.class);
259 if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
260 applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext,
261 fileDataCollection, filteredFiles, referenced);
265 fileDataCollection.addArtifactFiles(fileData);
266 filteredFiles.remove(fileData.getFile());
270 referenced.forEach(filteredFiles::remove);
271 if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
272 for (FileData fileData : fileDataCollection.getBaseFile()) {
273 filteredFiles.remove(fileData.getFile());
276 fileDataCollection.setAddOnFiles(filteredFiles.values());
277 return fileDataCollection;
280 private static void applyFilterOnFileCollection(
281 HeatOrchestrationTemplate heatOrchestrationTemplate,
282 TranslationContext translationContext,
283 FileDataCollection fileDataCollection, Map<String, FileData> filteredFiles,
284 Set<String> referenced) {
285 List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
287 for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
288 if (filenames.contains(resource.getType())) {
289 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
291 } else if (resource.getType()
292 .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
293 handleResourceGrpNestedFile(resource, translationContext, fileDataCollection,
294 filteredFiles, filenames, referenced);
299 private static void handleResourceGrpNestedFile(Resource resource,
300 TranslationContext translationContext,
301 FileDataCollection fileDataCollection,
302 Map<String, FileData> filteredFiles,
303 List<String> filenames,
304 Set<String> referenced) {
305 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
306 Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
307 if (innerTypeDef instanceof String) {
308 String internalResourceType = (String) innerTypeDef;
309 if (filenames.contains(internalResourceType)) {
310 handleNestedFile(translationContext, fileDataCollection, filteredFiles,
311 referenced, internalResourceType);
316 private static void handleNestedFile(TranslationContext translationContext,
317 FileDataCollection fileDataCollection,
318 Map<String, FileData> filteredFiles, Set<String> referenced,
319 String nestedFileName) {
320 referenced.add(nestedFileName);
321 fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
322 translationContext.getNestedHeatsFiles().add(nestedFileName);
325 private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
326 Set<FileData.Type> typesToGet) {
327 Map<String, FileData> filtered = new HashMap<>();
328 fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
329 .forEach(file -> filtered.put(file.getFile(), file));
333 private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
334 return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
338 * Extract attached resource id optional.
340 * @param translateTo the translate to
341 * @param propertyName the property name
342 * @return the optional
344 public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
345 String propertyName) {
346 Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
347 if (propertyValue == null) {
348 return Optional.empty();
350 return extractAttachedResourceId(translateTo.getHeatFileName(),
351 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(), propertyValue);
355 * Extract attached resource id optional.
357 * @param heatFileName the heat file name
358 * @param heatOrchestrationTemplate the heat orchestration template
359 * @param context the context
360 * @param propertyValue the property value
361 * @return the optional
363 public static Optional<AttachedResourceId> extractAttachedResourceId(
365 HeatOrchestrationTemplate heatOrchestrationTemplate,
366 TranslationContext context,
367 Object propertyValue) {
372 if (Objects.isNull(propertyValue)) {
373 return Optional.empty();
376 ReferenceType referenceType = ReferenceType.OTHER;
377 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
378 Map<String, Object> propMap = (Map) propertyValue;
379 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
380 entity = entry.getValue();
381 String key = entry.getKey();
382 referenceType = getReferenceTypeFromAttachedResouce(key);
384 if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
387 FunctionTranslator functionTranslator = new FunctionTranslator(getFunctionTranslateTo(null, null,
388 heatFileName, heatOrchestrationTemplate, context), null, entry.getValue(), null);
389 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
390 .translateFunction(functionTranslator);
392 if (translatedId instanceof String
393 && !new FunctionTranslator().isResourceSupported((String) translatedId)) {
398 translatedId = propertyValue;
399 entity = propertyValue;
402 return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
405 private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
406 ReferenceType referenceType;
409 referenceType = ReferenceType.GET_RESOURCE;
412 referenceType = ReferenceType.GET_PARAM;
415 referenceType = ReferenceType.GET_ATTR;
418 referenceType = ReferenceType.OTHER;
422 return referenceType;
426 * Gets contrail attached heat resource id.
428 * @param attachedResource the attached resource
429 * @return the contrail attached heat resource id
431 public static Optional<String> getContrailAttachedHeatResourceId(
432 AttachedResourceId attachedResource) {
433 if (attachedResource == null) {
434 return Optional.empty();
437 if (attachedResource.isGetResource()) {
438 return Optional.of((String) attachedResource.getEntityId());
441 if (attachedResource.isGetAttr()) {
442 return getResourceId(attachedResource.getEntityId());
444 return Optional.empty();
448 * Extract property optional.
450 * @param propertyValue the property value
451 * @return the optional
453 private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
454 Object attachedPropertyVal;
455 if (Objects.isNull(propertyValue)) {
456 return Optional.empty();
459 ReferenceType referenceType = ReferenceType.OTHER;
460 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
461 Map<String, Object> propMap = (Map) propertyValue;
462 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
463 attachedPropertyVal = entry.getValue();
464 String key = entry.getKey();
467 referenceType = ReferenceType.GET_RESOURCE;
470 referenceType = ReferenceType.GET_PARAM;
473 referenceType = ReferenceType.GET_ATTR;
480 attachedPropertyVal = propertyValue;
482 return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
488 * @param nodeTemplate the node template
489 * @param propertyKey the property key
491 public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
492 Object value = nodeTemplate.getProperties().get(propertyKey);
493 if (value != null && !(value instanceof Map)) {
494 nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
501 * @param nodeTemplate the node template
502 * @param propertyListKey the property list key
504 public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
505 Object listValue = nodeTemplate.getProperties().get(propertyListKey);
506 if (listValue instanceof List) {
507 List booleanList = (List) listValue;
508 for (int i = 0; i < booleanList.size(); i++) {
509 Object value = booleanList.get(i);
510 if (value != null && !(value instanceof Map)) {
511 booleanList.set(i, HeatBoolean.eval(value));
519 * Is yml file type boolean.
521 * @param filename the filename
522 * @return the boolean
524 public static boolean isYmlFileType(String filename) {
525 String extension = FilenameUtils.getExtension(filename);
526 return "yaml".equalsIgnoreCase(extension)
527 || "yml".equalsIgnoreCase(extension);
531 * Is nested resource boolean.
533 * @param resource the resource
534 * @return the boolean
536 public static boolean isNestedResource(Resource resource) {
537 String resourceType = resource.getType();
539 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
540 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
541 if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof
543 //currently only resource group which is poinitng to nested heat file is supported
544 //dynamic type is currently not supported
547 String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
548 .RESOURCE_DEF_TYPE_PROPERTY_NAME);
549 if (isYamlFile(internalResourceType)) {
552 } else if (isYamlFile(resourceType)) {
559 * Checks if the current HEAT resource if of type sub interface.
561 * @param resource the resource
562 * @return true if the resource is of sub interface type and false otherwise
564 public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
565 if (!ToggleableFeature.VLAN_TAGGING.isActive()) {
566 //Remove this once feature is stable and moved to production
569 //Check if resource group is a nested resource
570 if (!isNestedResource(resource)) {
573 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
574 return nestedHeatFileName.filter(fileName ->
575 isNestedVlanResource(fileName, context)).isPresent();
578 private static boolean isNestedVlanResource(String nestedHeatFileName,
579 TranslationContext translationContext) {
580 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
581 .yamlToObject(translationContext.getFileContent(nestedHeatFileName),
582 HeatOrchestrationTemplate.class);
583 return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())
584 && nestedHeatOrchestrationTemplate.getResources().values().stream()
585 .anyMatch(new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
588 public static Optional<String> getSubInterfaceParentPortNodeTemplateId(
589 TranslateTo subInterfaceTo) {
590 String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
591 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
592 .yamlToObject(subInterfaceTo.getContext().getFileContent(subInterfaceResourceType),
593 HeatOrchestrationTemplate.class);
594 if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
595 return Optional.empty();
597 for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate
598 .getResources().entrySet()) {
599 Resource resource = resourceEntry.getValue();
600 if (isVmiRefsPropertyExists(resource)) {
601 Object toscaPropertyValue =
602 TranslatorHeatToToscaPropertyConverter
603 .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
604 resourceEntry.getKey(), HeatConstants.VMI_REFS_PROPERTY_NAME,
605 resource.getProperties().get(HeatConstants.VMI_REFS_PROPERTY_NAME),
606 resource.getType(), subInterfaceResourceType, nestedHeatOrchestrationTemplate,
607 null, subInterfaceTo.getContext());
608 return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
611 return Optional.empty();
614 private static boolean isVmiRefsPropertyExists(Resource resource) {
615 return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
616 .getHeatResource().equals(resource.getType())
617 && MapUtils.isNotEmpty(resource.getProperties())
618 && resource.getProperties().containsKey(HeatConstants.VMI_REFS_PROPERTY_NAME);
621 public static String getSubInterfaceResourceType(Resource resource) {
622 if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
623 return ((Map) resource.getProperties()
624 .get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
625 .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME)
628 return resource.getType();
631 private static Optional<String> getParentNodeTemplateIdFromPropertyValue(
632 Object toscaPropertyValue,
633 TranslateTo subInterfaceTo) {
634 if (toscaPropertyValue instanceof List
635 && ((List) toscaPropertyValue).get(0) instanceof Map) {
636 Resource subInterfaceResource = subInterfaceTo.getResource();
637 Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
638 String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT
640 Map<String, Object> resourceDefPropertiesMap;
641 if (!isYamlFile(subInterfaceResource.getType())) {
642 resourceDefPropertiesMap = (Map) ((Map) subInterfaceResource
643 .getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
644 .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
646 resourceDefPropertiesMap = subInterfaceResource.getProperties();
648 Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
649 if (parentPortObj instanceof Map) {
650 Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
651 if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions
652 .GET_RESOURCE.getFunction())) {
653 return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
654 subInterfaceTo.getHeatOrchestrationTemplate(),
655 parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
656 subInterfaceTo.getContext());
660 return Optional.empty();
664 * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
665 * least one or more compute nodes).
667 * @param resource the resource
668 * @param context the context
669 * @return true if the resource represents a VFC and false otherwise.
671 public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
672 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
673 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
674 .yamlToObject(context.getFileContent(nestedHeatFileName.get()),
675 HeatOrchestrationTemplate.class);
676 if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
677 for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
678 if (ConsolidationDataUtil
679 .isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
688 * Get nested heat file name in case of nested resource.
690 * @param resource the resource
691 * @return the nested heat file name
693 private static Optional<String> getNestedHeatFileName(Resource resource) {
694 if (!isNestedResource(resource)) {
695 return Optional.empty();
698 String resourceType = resource.getType();
700 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
701 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
702 String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
703 .RESOURCE_DEF_TYPE_PROPERTY_NAME);
704 return Optional.of(internalResourceType);
706 return Optional.of(resourceType);
712 * @param resource the resource
713 * @return the nested file
715 public static Optional<String> getNestedFile(Resource resource) {
716 if (!isNestedResource(resource)) {
717 return Optional.empty();
719 String resourceType = resource.getType();
720 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
721 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
722 String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
723 .RESOURCE_DEF_TYPE_PROPERTY_NAME);
724 return Optional.of(internalResourceType);
726 return Optional.of(resourceType);
730 public static boolean isYamlFile(String fileName) {
731 return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
737 * @param heatOrchestrationTemplate the heat orchestration template
738 * @param resourceId the resource id
739 * @param heatFileName the heat file name
740 * @return the resource
742 public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate,
743 String resourceId, String heatFileName) {
744 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
745 if (resource == null) {
746 throw new CoreException(
747 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
756 * @param resourceId the resource id
757 * @param heatOrchestrationTemplate heat orchestration template
758 * @param heatFileName heat file name
759 * @return resource type
761 public static String getResourceType(String resourceId,
762 HeatOrchestrationTemplate heatOrchestrationTemplate,
763 String heatFileName) {
764 return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName)
769 * Is heat file nested boolean.
771 * @param translateTo the translate to
772 * @param heatFileName the heat file name
773 * @return the boolean
775 public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
776 return isHeatFileNested(translateTo.getContext(), heatFileName);
779 public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
780 return context.getNestedHeatsFiles().contains(heatFileName);
784 * Extract contrail get resource attached heat resource id optional.
786 * @param propertyValue the property value
787 * @return the optional
789 public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(
790 Object propertyValue) {
791 if (propertyValue instanceof Map) {
792 if (((Map) propertyValue).containsKey(GET_ATTR)) {
793 return getResourceId(((Map) propertyValue).get(GET_ATTR));
794 } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
795 return getHeatResourceIdFromResource((Map) propertyValue);
797 Collection valCollection = ((Map) propertyValue).values();
798 return evaluateHeatResourceId(valCollection);
800 } else if (propertyValue instanceof List) {
801 return evaluateHeatResourceId((List) propertyValue);
803 return Optional.empty();
806 private static Optional<String> getResourceId(Object data) {
807 if (data instanceof List && CollectionUtils.size(data) > 1
808 && FQ_NAME.equals(((List) data).get(1))
809 && ((List) data).get(0) instanceof String) {
810 return Optional.of((String) ((List) data).get(0));
812 LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
813 return Optional.empty();
817 private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
818 Object value = propertyValue.get(GET_RESOURCE);
819 if (value instanceof String) {
820 return Optional.of((String) value);
822 LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
823 return Optional.empty();
827 private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
828 for (Object prop : propertyValue) {
829 Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
830 if (ret.isPresent()) {
834 return Optional.empty();
838 * Gets tosca service model.
840 * @param context translation context
841 * @return the tosca service model
843 public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
844 Map<String, String> metadata = new HashMap<>();
845 metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
846 return getToscaServiceModel(context, metadata);
850 * Gets tosca service model.
852 * @param context translation context
853 * @param entryDefinitionMetadata template name of the entry definition servie template
854 * @return the tosca service model
856 private static ToscaServiceModel getToscaServiceModel(
857 TranslationContext context,
858 Map<String, String> entryDefinitionMetadata) {
859 Map<String, ServiceTemplate> serviceTemplates =
860 new HashMap<>(context.getGlobalServiceTemplates());
861 Collection<ServiceTemplate> tmpServiceTemplates =
862 context.getTranslatedServiceTemplates().values();
863 for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
864 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
866 return new ToscaServiceModel(null, serviceTemplates,
867 ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
871 * Gets service template from context.
873 * @param serviceTemplateFileName the service template file name
874 * @param context the context
875 * @return the service template from context
877 public static Optional<ServiceTemplate> getServiceTemplateFromContext(
878 String serviceTemplateFileName, TranslationContext context) {
879 for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
880 if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
881 return Optional.of(serviceTemplate);
884 return Optional.empty();
888 * Adding link requerment from port node template to network node template.
890 * @param portNodeTemplate port node template
891 * @param networkTranslatedId network node template id
893 public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
894 String networkTranslatedId) {
895 RequirementAssignment requirement = new RequirementAssignment();
896 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
897 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
898 requirement.setNode(networkTranslatedId);
899 DataModelUtil.addRequirementAssignment(portNodeTemplate,
900 ToscaConstants.LINK_REQUIREMENT_ID, requirement);
905 * Adding binding requerment from sub interface node template to interface (port) node template.
907 * @param subInterfaceNodeTemplate sub interface template
908 * @param interfaceTranslatedId interface node template id
910 public static void addBindingReqFromSubInterfaceToInterface(
911 NodeTemplate subInterfaceNodeTemplate, String interfaceTranslatedId) {
912 RequirementAssignment requirement = new RequirementAssignment();
913 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
914 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
915 requirement.setNode(interfaceTranslatedId);
917 .addRequirementAssignment(subInterfaceNodeTemplate,
918 ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
922 * Get property Parameter Name Value.
924 * @param property property
925 * @return Parameter name in case the property include "get_param" function
927 public static Optional<String> getPropertyParameterNameValue(Object property) {
928 if (Objects.isNull(property)) {
929 return Optional.empty();
931 Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
932 if (extractedProperty.isPresent()) {
933 return getParameterName(extractedProperty.get());
935 return Optional.empty();
938 private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
939 if (!extractedProperty.isGetParam()) {
940 return Optional.empty();
942 Object getParamFuncValue = extractedProperty.getPropertyValue();
943 if (getParamFuncValue instanceof String) {
944 return Optional.of((String) getParamFuncValue);
946 return Optional.of((String) ((List) getParamFuncValue).get(0));
950 public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
951 String heatPropertyName) {
952 return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
956 * Gets tosca property name.
958 * @param translateTo the translate to
959 * @param heatPropertyName the heat property name
960 * @return the tosca property name
962 public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
963 return translateTo.getContext()
964 .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
968 * Gets tosca attribute name.
970 * @param context the context
971 * @param heatResourceType the heat resource type
972 * @param heatAttrName the heat attr name
973 * @return the tosca attribute name
975 public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
976 String heatAttrName) {
977 return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
981 * Gets tosca attribute name.
983 * @param translateTo the translate to
984 * @param heatAttrName the heat attr name
985 * @return the tosca attribute name
987 public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
988 return translateTo.getContext()
989 .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
993 * Create init substitution service template service template.
995 * @param templateName the template name
996 * @return the service template
998 public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
999 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
1000 Map<String, String> templateMetadata = new HashMap<>();
1001 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
1002 nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
1003 nestedSubstitutionServiceTemplate
1004 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
1005 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
1006 List<Map<String, Import>> globalTypesImportList =
1007 GlobalTypesGenerator.getGlobalTypesImportList();
1008 globalTypesImportList.addAll(
1009 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1010 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
1011 return nestedSubstitutionServiceTemplate;
1015 * Create init global substitution service template service template.
1017 * @return the service template
1019 private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
1020 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
1021 Map<String, String> templateMetadata = new HashMap<>();
1022 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
1023 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1024 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
1025 globalSubstitutionServiceTemplate
1026 .setImports(GlobalTypesGenerator.getGlobalTypesImportList());
1027 globalSubstitutionServiceTemplate
1028 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
1029 return globalSubstitutionServiceTemplate;
1033 * Create substitution node type node type.
1035 * @param substitutionServiceTemplate the substitution service template
1036 * @return the node type
1038 public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
1039 NodeType substitutionNodeType = new NodeType();
1040 substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
1041 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
1042 substitutionNodeType
1043 .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
1044 substitutionNodeType
1045 .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
1046 return substitutionNodeType;
1049 private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
1050 ServiceTemplate substitutionServiceTemplate) {
1051 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
1052 Map<String, ParameterDefinition> properties =
1053 substitutionServiceTemplate.getTopology_template().getInputs();
1054 if (properties == null) {
1058 PropertyDefinition propertyDefinition;
1059 String toscaPropertyName;
1060 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
1061 toscaPropertyName = entry.getKey();
1062 propertyDefinition = new PropertyDefinition();
1063 ParameterDefinition parameterDefinition =
1064 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
1065 propertyDefinition.setType(parameterDefinition.getType());
1066 propertyDefinition.setDescription(parameterDefinition.getDescription());
1067 propertyDefinition.setRequired(parameterDefinition.getRequired());
1068 propertyDefinition.set_default(parameterDefinition.get_default());
1069 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
1070 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1071 propertyDefinition.setStatus(parameterDefinition.getStatus());
1072 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1074 return substitutionNodeTypeProperties;
1077 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
1078 ServiceTemplate substitutionServiceTemplate) {
1079 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1080 Map<String, ParameterDefinition> attributes =
1081 substitutionServiceTemplate.getTopology_template().getOutputs();
1082 if (attributes == null) {
1085 AttributeDefinition attributeDefinition;
1086 String toscaAttributeName;
1088 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1089 attributeDefinition = new AttributeDefinition();
1090 toscaAttributeName = entry.getKey();
1091 ParameterDefinition parameterDefinition =
1092 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1093 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1094 attributeDefinition.setType(parameterDefinition.getType());
1096 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1098 attributeDefinition.setDescription(parameterDefinition.getDescription());
1099 attributeDefinition.set_default(parameterDefinition.get_default());
1100 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1101 attributeDefinition.setStatus(parameterDefinition.getStatus());
1102 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1104 return substitutionNodeTypeAttributes;
1109 * Create and add substitution mapping to the nested substitution service template, and update
1110 * the subtitution node type accordingly with the exposed requerments and capabilities
1112 * @param context the translation context
1113 * @param substitutionNodeTypeKey the substitution node type key
1114 * @param nestedSubstitutionServiceTemplate the nested substitution service template
1115 * @param substitutionNodeType the substitution node type
1117 public static void handleSubstitutionMapping(
1118 TranslationContext context,
1119 String substitutionNodeTypeKey,
1120 ServiceTemplate nestedSubstitutionServiceTemplate,
1121 NodeType substitutionNodeType) {
1122 Map<String, Map<String, List<String>>> substitutionMapping =
1123 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
1124 nestedSubstitutionServiceTemplate, context);
1125 //add substitution mapping after capability and requirement expose calculation
1126 nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
1127 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeKey,
1128 substitutionNodeType, substitutionMapping));
1132 * Gets node type with flat hierarchy.
1134 * @param nodeTypeId the node type id
1135 * @param serviceTemplate the service template
1136 * @param context the context
1137 * @return the node type with flat hierarchy
1139 public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId,
1140 ServiceTemplate serviceTemplate,
1141 TranslationContext context) {
1142 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1143 ToscaServiceModel toscaServiceModel = HeatToToscaUtil
1144 .getToscaServiceModel(context, serviceTemplate.getMetadata());
1145 return (NodeType) toscaAnalyzerService
1146 .getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate, toscaServiceModel);
1150 * Create substitution node template node template.
1152 * @param translateTo the translate to
1153 * @param templateName the template name
1154 * @param substitutionNodeTypeKey the substitution node type key
1155 * @return the node template
1157 public NodeTemplate createSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1158 String substitutionNodeTypeKey) {
1159 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1160 List<String> directiveList = new ArrayList<>();
1161 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1162 substitutionNodeTemplate.setDirectives(directiveList);
1163 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1164 substitutionNodeTemplate.setProperties(
1165 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
1167 return substitutionNodeTemplate;
1171 * Create abstract substitution node template.
1173 * @param translateTo the translate to
1174 * @param templateName the template name
1175 * @param substitutionNodeTypeKey the substitution node type key
1176 * @return the abstract substitute node template
1178 public static NodeTemplate createAbstractSubstitutionNodeTemplate(
1179 TranslateTo translateTo,
1180 String templateName,
1181 String substitutionNodeTypeKey) {
1182 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1183 List<String> directiveList = new ArrayList<>();
1184 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1185 substitutionNodeTemplate.setDirectives(directiveList);
1186 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1187 substitutionNodeTemplate.setProperties(
1188 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
1190 return substitutionNodeTemplate;
1195 * Checks if the source and target resource is a valid candidate for adding tosca dependency
1198 * @param sourceResource the source resource
1199 * @param targetResource the target resource
1200 * @param dependencyEntity the dependency entity
1201 * @return true if the candidate resources are a valid combination for the dependency relationship
1202 * and false otherwise
1204 public static boolean isValidDependsOnCandidate(Resource sourceResource,
1205 Resource targetResource,
1206 ConsolidationEntityType dependencyEntity,
1207 TranslationContext context) {
1208 dependencyEntity.setEntityType(sourceResource, targetResource, context);
1209 ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1210 ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1212 return ConsolidationTypesConnectivity
1213 .isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
1216 private static Map<String, Object> managerSubstitutionNodeTemplateProperties(
1217 TranslateTo translateTo,
1219 String templateName) {
1220 Map<String, Object> substitutionProperties = new HashMap<>();
1221 Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1222 if (Objects.nonNull(heatProperties)) {
1223 for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1224 Object property = TranslatorHeatToToscaPropertyConverter
1225 .getToscaPropertyValue(translateTo.getServiceTemplate(),
1226 translateTo.getTranslatedId(), entry.getKey(),
1227 entry.getValue(), null, translateTo.getHeatFileName(),
1228 translateTo.getHeatOrchestrationTemplate(), template, translateTo.getContext());
1229 substitutionProperties.put(entry.getKey(), property);
1232 return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1235 private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1237 substitutionProperties) {
1238 Map<String, Object> innerProps = new HashMap<>();
1239 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1240 ToscaUtil.getServiceTemplateFileName(templateName));
1241 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1242 return substitutionProperties;
1245 private static Map<String, Map<String, List<String>>>
1246 getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1247 ServiceTemplate substitutionServiceTemplate,
1248 TranslationContext context) {
1249 Map<String, NodeTemplate> nodeTemplates =
1250 substitutionServiceTemplate.getTopology_template().getNode_templates();
1251 String nodeTemplateId;
1252 NodeTemplate nodeTemplate;
1254 Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1255 if (nodeTemplates == null) {
1256 return substitutionMapping;
1259 Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1260 Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1261 substitutionMapping.put("capability", capabilitySubstitutionMapping);
1262 substitutionMapping.put("requirement", requirementSubstitutionMapping);
1263 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1264 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1265 List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1266 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition =
1268 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1269 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1270 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1272 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1273 nodeTemplateId = entry.getKey();
1274 nodeTemplate = entry.getValue();
1275 nodeType = nodeTemplate.getType();
1278 nodeTypeRequirementsDefinition =
1279 getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1280 requirementSubstitutionMapping, context);
1281 nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1282 fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1283 //set substitution node type requirements
1284 exposedRequirementsDefinition =
1285 toscaAnalyzerService.calculateExposedRequirements(nodeTypeRequirementsDefinition,
1286 nodeTemplateRequirementsAssignment);
1288 .addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1292 addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition,
1293 capabilitySubstitutionMapping, nodeType,
1294 nodeTemplateId, substitutionServiceTemplate, context);
1297 exposedCapabilitiesDefinition =
1298 toscaAnalyzerService.calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1299 fullFilledRequirementsDefinition);
1300 DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1301 return substitutionMapping;
1304 private static void addNodeTypeCapabilitiesToSubMapping(
1305 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1306 Map<String, List<String>> capabilitySubstitutionMapping, String type, String templateName,
1307 ServiceTemplate serviceTemplate, TranslationContext context) {
1308 NodeType flatNodeType =
1309 getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1311 if (flatNodeType.getCapabilities() != null) {
1312 flatNodeType.getCapabilities()
1315 .forEach(capabilityNodeEntry ->
1316 addCapabilityToSubMapping(
1317 templateName, capabilityNodeEntry, nodeTypeCapabilitiesDefinition,
1318 capabilitySubstitutionMapping));
1322 public static boolean shouldAnnotationsToBeAdded() {
1323 return ToggleableFeature.ANNOTATIONS.isActive();
1326 private static void addCapabilityToSubMapping(String templateName,
1327 Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
1328 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1329 Map<String, List<String>> capabilitySubstitutionMapping) {
1330 String capabilityKey;
1331 List<String> capabilityMapping;
1332 capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
1333 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1334 capabilityMapping = new ArrayList<>();
1335 capabilityMapping.add(templateName);
1336 capabilityMapping.add(capabilityNodeEntry.getKey());
1337 capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1340 private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(
1342 String templateName,
1343 ServiceTemplate serviceTemplate,
1344 Map<String, List<String>> requirementSubstitutionMapping,
1345 TranslationContext context) {
1346 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1347 NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1348 List<String> requirementMapping;
1350 if (flatNodeType.getRequirements() == null) {
1351 return requirementList;
1354 for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1355 for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap
1357 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1358 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil
1359 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1360 RequirementDefinition.class);
1361 if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
1362 requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
1364 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1365 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1366 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1367 requirementMapping = new ArrayList<>();
1368 requirementMapping.add(templateName);
1369 requirementMapping.add(requirementNodeEntry.getKey());
1370 requirementSubstitutionMapping
1371 .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
1372 if (Objects.isNull(requirementNodeEntryValue.getNode())) {
1373 requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
1377 return requirementList;
1381 * Fetch global substitution service template service template.
1383 * @param serviceTemplate the service template
1384 * @param context the context
1385 * @return the service template
1387 public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(
1388 ServiceTemplate serviceTemplate,
1389 TranslationContext context) {
1390 ServiceTemplate globalSubstitutionServiceTemplate =
1391 context.getTranslatedServiceTemplates()
1392 .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1393 if (globalSubstitutionServiceTemplate == null) {
1394 globalSubstitutionServiceTemplate =
1395 HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1396 context.getTranslatedServiceTemplates()
1397 .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
1398 globalSubstitutionServiceTemplate);
1400 boolean isImportAddedToServiceTemplate =
1401 DataModelUtil.isImportAddedToServiceTemplate(serviceTemplate.getImports(), Constants
1402 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1403 if (!isImportAddedToServiceTemplate) {
1404 serviceTemplate.getImports()
1406 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1408 return globalSubstitutionServiceTemplate;
1411 public static List<Map<String, Import>> createImportList(String templateName) {
1412 List<Map<String, Import>> imports = new ArrayList<>();
1413 Map<String, Import> importsMap = new HashMap<>();
1414 importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1415 imports.add(importsMap);
1420 * Create service template import import.
1422 * @param serviceTemplate the service template
1423 * @return the import
1425 public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1426 Import serviceTemplateImport = new Import();
1427 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1428 return serviceTemplateImport;
1432 * Create service template import import.
1434 * @param metadataTemplateName the service template name
1435 * @return the import
1437 private static Import createServiceTemplateImport(String metadataTemplateName) {
1438 Import serviceTemplateImport = new Import();
1439 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1440 return serviceTemplateImport;
1443 public static ToscaServiceModel createToscaServiceModel(ServiceTemplate
1444 entryDefinitionServiceTemplate,
1445 TranslationContext translationContext) {
1446 return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
1447 getServiceTemplates(translationContext),
1448 ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1451 private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1452 FileContentHandler artifactFiles = new FileContentHandler();
1453 artifactFiles.setFiles(translationContext.getFiles());
1454 artifactFiles.setFiles(translationContext.getExternalArtifacts());
1456 HeatTreeManager heatTreeManager =
1457 HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1458 heatTreeManager.createTree();
1459 ValidationStructureList validationStructureList =
1460 new ValidationStructureList(heatTreeManager.getTree());
1461 byte[] validationStructureFile =
1462 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1463 artifactFiles.addFile("HEAT.meta", validationStructureFile);
1464 return artifactFiles;
1468 private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext
1469 translationContext) {
1470 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1471 serviceTemplates.addAll(GlobalTypesGenerator
1472 .getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
1473 serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1474 Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1476 for (ServiceTemplate template : serviceTemplates) {
1477 serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1479 return serviceTemplatesMap;
1482 public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
1483 if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext())
1484 && isSubInterfaceBoundToPort(translateTo)) {
1485 return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
1487 return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
1490 private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
1491 return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
1494 //Method evaluate the network role from sub interface node template id, designed considering
1495 // only single sub interface present in nested file else it will return null
1496 public static Optional<String> getNetworkRoleFromSubInterfaceId(Resource resource,
1497 TranslationContext translationContext) {
1498 Optional<String> networkRole = Optional.empty();
1499 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
1501 if (!nestedHeatFileName.isPresent()) {
1505 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
1506 .yamlToObject(translationContext.getFileContent(nestedHeatFileName.get()),
1507 HeatOrchestrationTemplate.class);
1509 if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
1510 ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
1511 new ContrailV2VirtualMachineInterfaceHelper();
1512 Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
1513 nestedHeatOrchestrationTemplate
1514 .getResources().entrySet().stream()
1515 .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
1516 .isVlanSubInterfaceResource(resourceEntry.getValue()))
1518 if (vlanSubInterfaceResource.isPresent()) {
1519 Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
1520 networkRole = extractNetworkRoleFromSubInterfaceId(vlanSubInterfaceResourceEntry.getKey(),
1521 vlanSubInterfaceResourceEntry.getValue().getType());
1527 public static Optional<String> evaluateNetworkRoleFromResourceId(String resourceId,
1528 String resourceType) {
1529 Optional<PortType> portType = getPortType(resourceType);
1530 if (portType.isPresent()) {
1531 String portResourceIdRegex =
1532 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + WORDS_REGEX + UNDERSCORE
1533 + portType.get().getPortTypeName() + PORT_RESOURCE_ID_REGEX_SUFFIX;
1534 String portIntResourceIdRegex =
1535 PORT_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
1536 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1538 String portNetworkRole = getNetworkRole(resourceId, portResourceIdRegex);
1539 String portIntNetworkRole = getNetworkRole(resourceId, portIntResourceIdRegex);
1541 return Optional.ofNullable(Objects.nonNull(portNetworkRole)
1542 ? portNetworkRole : portIntNetworkRole);
1544 return Optional.empty();
1547 private static Optional<PortType> getPortType(String resourceType) {
1548 if (resourceType.equals(
1549 HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
1550 return Optional.of(PortType.VMI);
1551 } else if (resourceType.equals(
1552 HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
1553 return Optional.of(PortType.PORT);
1555 return Optional.empty();
1558 public static Optional<String> extractNetworkRoleFromSubInterfaceId(String resourceId,
1559 String resourceType) {
1560 Optional<PortType> portType = getPortType(resourceType);
1561 if (portType.isPresent()) {
1562 String subInterfaceResourceIdRegex =
1563 SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
1564 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1566 return Optional.ofNullable(getNetworkRole(resourceId, subInterfaceResourceIdRegex));
1568 return Optional.empty();
1571 private enum PortType {
1575 private String portTypeName;
1577 PortType(String portTypeName) {
1578 this.portTypeName = portTypeName;
1581 public String getPortTypeName() {
1582 return portTypeName;
1586 private static String getNetworkRole(String portResourceId, String portIdRegex) {
1587 Pattern pattern = Pattern.compile(portIdRegex);
1588 Matcher matcher = pattern.matcher(portResourceId);
1589 if (matcher.matches()) {
1590 String networkRole = matcher.group(3);
1591 //Assuming network role will not contain ONLY digits
1592 if (!networkRole.matches("\\d+")) {
1593 return matcher.group(3);