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 = WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX;
117 private static final String PORT_INT_RESOURCE_ID_REGEX_PREFIX =
118 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + "int_" + WORDS_REGEX + UNDERSCORE;
119 private static final String SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX =
120 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + "subint_" + WORDS_REGEX + UNDERSCORE;
121 private static final String SUB_INTERFACE_REGEX =
122 WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX + "_subint_(\\w_+)*vmi" + PORT_RESOURCE_ID_REGEX_SUFFIX;
125 * Load and translate template data translator output.
127 * @param fileNameContentMap the file name content map
128 * @return the translator output
130 public static TranslatorOutput loadAndTranslateTemplateData(FileContentHandler fileNameContentMap) {
131 HeatToToscaTranslator heatToToscaTranslator = HeatToToscaTranslatorFactory.getInstance().createInterface();
133 try (InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME)) {
134 heatToToscaTranslator.addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
135 } catch (IOException e) {
136 throw new RuntimeException("Failed to read manifest", e);
139 fileNameContentMap.getFileList().stream().filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME)))
140 .forEach(fileName -> heatToToscaTranslator.addFile(fileName,
141 FileUtils.toByteArray(fileNameContentMap.getFileContent(fileName))));
143 Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
144 if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
145 TranslatorOutput translatorOutput = new TranslatorOutput();
146 translatorOutput.setErrorMessages(errors);
147 return translatorOutput;
150 try (InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap)) {
151 heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
152 return heatToToscaTranslator.translate();
153 } catch (IOException e) {
154 // rethrow as a RuntimeException to keep the signature backward compatible
155 throw new RuntimeException("Failed to read Heat template tree", e);
160 private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
161 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
162 heatTreeManager.createTree();
163 HeatStructureTree tree = heatTreeManager.getTree();
164 ValidationStructureList validationStructureList = new ValidationStructureList(tree);
165 return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
169 * Build list of files to search optional.
171 * @param heatFileName the heat file name
172 * @param filesDataList the files data list
173 * @param types the types
174 * @return the optional
176 public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName, List<FileData> filesDataList,
177 FileData.Type... types) {
178 List<FileData> list = new ArrayList<>(filesDataList);
179 Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
180 if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
181 list.addAll(resourceFileData.get().getData());
183 return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
187 * Gets filtered list of file data by types.
189 * @param filesToSearch the files to search
190 * @param types the types
191 * @return the filtered list of file data by types
193 public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
194 FileData.Type... types) {
195 return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types)).collect(Collectors.toList());
199 * Gets file data from the list according to the input heat file name.
201 * @param heatFileName the heat file name
202 * @param fileDataList the file data list
203 * @return the file data
205 public static Optional<FileData> getFileData(String heatFileName, Collection<FileData> fileDataList) {
206 for (FileData file : fileDataList) {
207 if (file.getFile().equals(heatFileName)) {
208 return Optional.of(file);
211 return Optional.empty();
215 * Gets file data which is supported by the translator, from the context according the input heat
218 * @param heatFileName the heat file name
219 * @param context the translation context
220 * @return the file data
222 public static FileData getFileData(String heatFileName, TranslationContext context) {
223 List<FileData> fileDataList = context.getManifest().getContent().getData();
224 for (FileData fileData : fileDataList) {
225 if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType()) && fileData.getFile()
226 .equals(heatFileName)) {
233 static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList, 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().yamlToObject(
247 translationContext.getFileContent(fileName), HeatOrchestrationTemplate.class);
248 if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
249 applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext, fileDataCollection,
250 filteredFiles, referenced);
254 fileDataCollection.addArtifactFiles(fileData);
255 filteredFiles.remove(fileData.getFile());
259 referenced.forEach(filteredFiles::remove);
260 if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
261 for (FileData fileData : fileDataCollection.getBaseFile()) {
262 filteredFiles.remove(fileData.getFile());
265 fileDataCollection.setAddOnFiles(filteredFiles.values());
266 return fileDataCollection;
269 private static void applyFilterOnFileCollection(HeatOrchestrationTemplate heatOrchestrationTemplate,
270 TranslationContext translationContext,
271 FileDataCollection fileDataCollection,
272 Map<String, FileData> filteredFiles,
273 Set<String> referenced) {
274 List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
276 for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
277 if (filenames.contains(resource.getType())) {
278 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced, resource.getType());
279 } else if (resource.getType().equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
280 handleResourceGrpNestedFile(resource, translationContext, fileDataCollection, filteredFiles, filenames,
286 private static void handleResourceGrpNestedFile(Resource resource, TranslationContext translationContext,
287 FileDataCollection fileDataCollection,
288 Map<String, FileData> filteredFiles, List<String> filenames,
289 Set<String> referenced) {
290 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
291 Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
292 if (innerTypeDef instanceof String) {
293 String internalResourceType = (String) innerTypeDef;
294 if (filenames.contains(internalResourceType)) {
295 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
296 internalResourceType);
301 private static void handleNestedFile(TranslationContext translationContext, FileDataCollection fileDataCollection,
302 Map<String, FileData> filteredFiles, Set<String> referenced,
303 String nestedFileName) {
304 referenced.add(nestedFileName);
305 fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
306 translationContext.getNestedHeatsFiles().add(nestedFileName);
309 private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
310 Set<FileData.Type> typesToGet) {
311 Map<String, FileData> filtered = new HashMap<>();
312 fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
313 .forEach(file -> filtered.put(file.getFile(), file));
317 private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
318 return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
322 * Extract attached resource id optional.
324 * @param translateTo the translate to
325 * @param propertyName the property name
326 * @return the optional
328 public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo, String propertyName) {
329 Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
330 if (propertyValue == null) {
331 return Optional.empty();
333 return extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
334 translateTo.getContext(), propertyValue);
338 * Extract attached resource id optional.
340 * @param heatFileName the heat file name
341 * @param heatOrchestrationTemplate the heat orchestration template
342 * @param context the context
343 * @param propertyValue the property value
344 * @return the optional
346 public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
347 HeatOrchestrationTemplate heatOrchestrationTemplate,
348 TranslationContext context,
349 Object propertyValue) {
354 if (Objects.isNull(propertyValue)) {
355 return Optional.empty();
358 ReferenceType referenceType = ReferenceType.OTHER;
359 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
360 Map<String, Object> propMap = (Map) propertyValue;
361 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
362 entity = entry.getValue();
363 String key = entry.getKey();
364 referenceType = getReferenceTypeFromAttachedResouce(key);
366 if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
369 FunctionTranslator functionTranslator = new FunctionTranslator(getFunctionTranslateTo(null, null,
370 heatFileName, heatOrchestrationTemplate, context), null, entry.getValue(), null);
371 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
372 .translateFunction(functionTranslator);
374 if (translatedId instanceof String
375 && !new FunctionTranslator().isResourceSupported((String) translatedId)) {
380 translatedId = propertyValue;
381 entity = propertyValue;
384 return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
387 private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
388 ReferenceType referenceType;
391 referenceType = ReferenceType.GET_RESOURCE;
394 referenceType = ReferenceType.GET_PARAM;
397 referenceType = ReferenceType.GET_ATTR;
400 referenceType = ReferenceType.OTHER;
404 return referenceType;
408 * Gets contrail attached heat resource id.
410 * @param attachedResource the attached resource
411 * @return the contrail attached heat resource id
413 public static Optional<String> getContrailAttachedHeatResourceId(AttachedResourceId attachedResource) {
414 if (attachedResource == null) {
415 return Optional.empty();
418 if (attachedResource.isGetResource()) {
419 return Optional.of((String) attachedResource.getEntityId());
422 if (attachedResource.isGetAttr()) {
423 return getResourceId(attachedResource.getEntityId());
425 return Optional.empty();
429 * Extract property optional.
431 * @param propertyValue the property value
432 * @return the optional
434 private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
435 Object attachedPropertyVal;
436 if (Objects.isNull(propertyValue)) {
437 return Optional.empty();
440 ReferenceType referenceType = ReferenceType.OTHER;
441 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
442 Map<String, Object> propMap = (Map) propertyValue;
443 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
444 attachedPropertyVal = entry.getValue();
445 String key = entry.getKey();
448 referenceType = ReferenceType.GET_RESOURCE;
451 referenceType = ReferenceType.GET_PARAM;
454 referenceType = ReferenceType.GET_ATTR;
461 attachedPropertyVal = propertyValue;
463 return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
469 * @param nodeTemplate the node template
470 * @param propertyKey the property key
472 public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
473 Object value = nodeTemplate.getProperties().get(propertyKey);
474 if (value != null && !(value instanceof Map)) {
475 nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
482 * @param nodeTemplate the node template
483 * @param propertyListKey the property list key
485 public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
486 Object listValue = nodeTemplate.getProperties().get(propertyListKey);
487 if (listValue instanceof List) {
488 List booleanList = (List) listValue;
489 for (int i = 0; i < booleanList.size(); i++) {
490 Object value = booleanList.get(i);
491 if (value != null && !(value instanceof Map)) {
492 booleanList.set(i, HeatBoolean.eval(value));
500 * Is yml file type boolean.
502 * @param filename the filename
503 * @return the boolean
505 public static boolean isYmlFileType(String filename) {
506 String extension = FilenameUtils.getExtension(filename);
507 return "yaml".equalsIgnoreCase(extension) || "yml".equalsIgnoreCase(extension);
511 * Is nested resource boolean.
513 * @param resource the resource
514 * @return the boolean
516 public static boolean isNestedResource(Resource resource) {
517 String resourceType = resource.getType();
519 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
520 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
521 if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof String)) {
522 //currently only resource group which is poinitng to nested heat file is supported
523 //dynamic type is currently not supported
526 String internalResourceType =
527 (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
528 if (isYamlFile(internalResourceType)) {
531 } else if (isYamlFile(resourceType)) {
538 * Checks if the current HEAT resource if of type sub interface.
540 * @param resource the resource
541 * @return true if the resource is of sub interface type and false otherwise
543 public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
544 if (!ToggleableFeature.VLAN_TAGGING.isActive()) {
545 //Remove this once feature is stable and moved to production
548 //Check if resource group is a nested resource
549 if (!isNestedResource(resource)) {
552 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
553 return nestedHeatFileName.filter(fileName -> isNestedVlanResource(fileName, context)).isPresent();
556 private static boolean isNestedVlanResource(String nestedHeatFileName, TranslationContext translationContext) {
557 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
558 translationContext.getFileContent(nestedHeatFileName), HeatOrchestrationTemplate.class);
559 return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources()) && nestedHeatOrchestrationTemplate
560 .getResources().values()
562 new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
565 public static Optional<String> getSubInterfaceParentPortNodeTemplateId(TranslateTo subInterfaceTo) {
566 String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
567 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
568 subInterfaceTo.getContext().getFileContent(subInterfaceResourceType), HeatOrchestrationTemplate.class);
569 if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
570 return Optional.empty();
572 for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate.getResources().entrySet()) {
573 Resource resource = resourceEntry.getValue();
574 if (isVmiRefsPropertyExists(resource)) {
575 Object toscaPropertyValue = TranslatorHeatToToscaPropertyConverter
576 .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
577 resourceEntry.getKey(),
578 HeatConstants.VMI_REFS_PROPERTY_NAME,
579 resource.getProperties()
580 .get(HeatConstants.VMI_REFS_PROPERTY_NAME),
581 resource.getType(), subInterfaceResourceType,
582 nestedHeatOrchestrationTemplate, null,
583 subInterfaceTo.getContext());
584 return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
587 return Optional.empty();
590 private static boolean isVmiRefsPropertyExists(Resource resource) {
591 return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource()
592 .equals(resource.getType())
593 && MapUtils.isNotEmpty(resource.getProperties()) && resource.getProperties().containsKey(
594 HeatConstants.VMI_REFS_PROPERTY_NAME);
597 public static String getSubInterfaceResourceType(Resource resource) {
598 if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
599 return ((Map) resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
600 .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME).toString();
602 return resource.getType();
605 private static Optional<String> getParentNodeTemplateIdFromPropertyValue(Object toscaPropertyValue,
606 TranslateTo subInterfaceTo) {
607 if (toscaPropertyValue instanceof List && ((List) toscaPropertyValue).get(0) instanceof Map) {
608 Resource subInterfaceResource = subInterfaceTo.getResource();
609 Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
610 String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT.getDisplayName());
611 Map<String, Object> resourceDefPropertiesMap;
612 if (!isYamlFile(subInterfaceResource.getType())) {
613 resourceDefPropertiesMap =
614 (Map) ((Map) subInterfaceResource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
615 .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
617 resourceDefPropertiesMap = subInterfaceResource.getProperties();
619 Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
620 if (parentPortObj instanceof Map) {
621 Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
622 if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions.GET_RESOURCE.getFunction())) {
623 return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
624 subInterfaceTo.getHeatOrchestrationTemplate(),
625 parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
626 subInterfaceTo.getContext());
630 return Optional.empty();
634 * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
635 * least one or more compute nodes).
637 * @param resource the resource
638 * @param context the context
639 * @return true if the resource represents a VFC and false otherwise.
641 public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
642 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
643 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
644 context.getFileContent(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
645 if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
646 for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
647 if (ConsolidationDataUtil.isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
656 * Get nested heat file name in case of nested resource.
658 * @param resource the resource
659 * @return the nested heat file name
661 private static Optional<String> getNestedHeatFileName(Resource resource) {
662 if (!isNestedResource(resource)) {
663 return Optional.empty();
666 String resourceType = resource.getType();
668 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
669 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
670 String internalResourceType =
671 (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
672 return Optional.of(internalResourceType);
674 return Optional.of(resourceType);
680 * @param resource the resource
681 * @return the nested file
683 public static Optional<String> getNestedFile(Resource resource) {
684 if (!isNestedResource(resource)) {
685 return Optional.empty();
687 String resourceType = resource.getType();
688 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
689 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
690 String internalResourceType =
691 (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
692 return Optional.of(internalResourceType);
694 return Optional.of(resourceType);
698 public static boolean isYamlFile(String fileName) {
699 return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
705 * @param heatOrchestrationTemplate the heat orchestration template
706 * @param resourceId the resource id
707 * @param heatFileName the heat file name
708 * @return the resource
710 public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate, String resourceId,
711 String heatFileName) {
712 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
713 if (resource == null) {
714 throw new CoreException(new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
723 * @param resourceId the resource id
724 * @param heatOrchestrationTemplate heat orchestration template
725 * @param heatFileName heat file name
726 * @return resource type
728 public static String getResourceType(String resourceId, HeatOrchestrationTemplate heatOrchestrationTemplate,
729 String heatFileName) {
730 return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName).getType();
734 * Is heat file nested boolean.
736 * @param translateTo the translate to
737 * @param heatFileName the heat file name
738 * @return the boolean
740 public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
741 return isHeatFileNested(translateTo.getContext(), heatFileName);
744 public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
745 return context.getNestedHeatsFiles().contains(heatFileName);
749 * Extract contrail get resource attached heat resource id optional.
751 * @param propertyValue the property value
752 * @return the optional
754 public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(Object propertyValue) {
755 if (propertyValue instanceof Map) {
756 if (((Map) propertyValue).containsKey(GET_ATTR)) {
757 return getResourceId(((Map) propertyValue).get(GET_ATTR));
758 } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
759 return getHeatResourceIdFromResource((Map) propertyValue);
761 Collection valCollection = ((Map) propertyValue).values();
762 return evaluateHeatResourceId(valCollection);
764 } else if (propertyValue instanceof List) {
765 return evaluateHeatResourceId((List) propertyValue);
767 return Optional.empty();
770 private static Optional<String> getResourceId(Object data) {
771 if (data instanceof List && CollectionUtils.size(data) > 1 && FQ_NAME.equals(((List) data).get(1))
772 && ((List) data).get(0) instanceof String) {
773 return Optional.of((String) ((List) data).get(0));
775 LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
776 return Optional.empty();
780 private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
781 Object value = propertyValue.get(GET_RESOURCE);
782 if (value instanceof String) {
783 return Optional.of((String) value);
785 LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
786 return Optional.empty();
790 private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
791 for (Object prop : propertyValue) {
792 Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
793 if (ret.isPresent()) {
797 return Optional.empty();
801 * Gets tosca service model.
803 * @param context translation context
804 * @return the tosca service model
806 public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
807 Map<String, String> metadata = new HashMap<>();
808 metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
809 return getToscaServiceModel(context, metadata);
813 * Gets tosca service model.
815 * @param context translation context
816 * @param entryDefinitionMetadata template name of the entry definition servie template
817 * @return the tosca service model
819 private static ToscaServiceModel getToscaServiceModel(TranslationContext context,
820 Map<String, String> entryDefinitionMetadata) {
821 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(context.getGlobalServiceTemplates());
822 Collection<ServiceTemplate> tmpServiceTemplates = context.getTranslatedServiceTemplates().values();
823 for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
824 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
826 return new ToscaServiceModel(null, serviceTemplates,
827 ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
831 * Gets service template from context.
833 * @param serviceTemplateFileName the service template file name
834 * @param context the context
835 * @return the service template from context
837 public static Optional<ServiceTemplate> getServiceTemplateFromContext(String serviceTemplateFileName,
838 TranslationContext context) {
839 for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
840 if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
841 return Optional.of(serviceTemplate);
844 return Optional.empty();
848 * Adding link requerment from port node template to network node template.
850 * @param portNodeTemplate port node template
851 * @param networkTranslatedId network node template id
853 public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
854 String networkTranslatedId) {
855 RequirementAssignment requirement = new RequirementAssignment();
856 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
857 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
858 requirement.setNode(networkTranslatedId);
859 DataModelUtil.addRequirementAssignment(portNodeTemplate, ToscaConstants.LINK_REQUIREMENT_ID, requirement);
864 * Adding binding requerment from sub interface node template to interface (port) node template.
866 * @param subInterfaceNodeTemplate sub interface template
867 * @param interfaceTranslatedId interface node template id
869 public static void addBindingReqFromSubInterfaceToInterface(NodeTemplate subInterfaceNodeTemplate,
870 String interfaceTranslatedId) {
871 RequirementAssignment requirement = new RequirementAssignment();
872 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
873 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
874 requirement.setNode(interfaceTranslatedId);
876 .addRequirementAssignment(subInterfaceNodeTemplate, ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
880 * Get property Parameter Name Value.
882 * @param property property
883 * @return Parameter name in case the property include "get_param" function
885 public static Optional<String> getPropertyParameterNameValue(Object property) {
886 if (Objects.isNull(property)) {
887 return Optional.empty();
889 Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
890 if (extractedProperty.isPresent()) {
891 return getParameterName(extractedProperty.get());
893 return Optional.empty();
896 private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
897 if (!extractedProperty.isGetParam()) {
898 return Optional.empty();
900 Object getParamFuncValue = extractedProperty.getPropertyValue();
901 if (getParamFuncValue instanceof String) {
902 return Optional.of((String) getParamFuncValue);
904 return Optional.of((String) ((List) getParamFuncValue).get(0));
908 public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
909 String heatPropertyName) {
910 return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
914 * Gets tosca property name.
916 * @param translateTo the translate to
917 * @param heatPropertyName the heat property name
918 * @return the tosca property name
920 public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
921 return translateTo.getContext()
922 .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
926 * Gets tosca attribute name.
928 * @param context the context
929 * @param heatResourceType the heat resource type
930 * @param heatAttrName the heat attr name
931 * @return the tosca attribute name
933 public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
934 String heatAttrName) {
935 return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
939 * Gets tosca attribute name.
941 * @param translateTo the translate to
942 * @param heatAttrName the heat attr name
943 * @return the tosca attribute name
945 public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
946 return translateTo.getContext()
947 .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
951 * Create init substitution service template service template.
953 * @param templateName the template name
954 * @return the service template
956 public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
957 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
958 Map<String, String> templateMetadata = new HashMap<>();
959 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
960 nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
961 nestedSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
962 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
963 List<Map<String, Import>> globalTypesImportList = GlobalTypesGenerator.getGlobalTypesImportList();
964 globalTypesImportList
965 .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
966 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
967 return nestedSubstitutionServiceTemplate;
971 * Create init global substitution service template service template.
973 * @return the service template
975 private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
976 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
977 Map<String, String> templateMetadata = new HashMap<>();
979 .put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
980 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
981 globalSubstitutionServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
982 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
983 return globalSubstitutionServiceTemplate;
987 * Create substitution node type node type.
989 * @param substitutionServiceTemplate the substitution service template
990 * @return the node type
992 public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
993 NodeType substitutionNodeType = new NodeType();
994 substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
995 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
996 substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
997 substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
998 return substitutionNodeType;
1001 private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
1002 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
1003 Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
1004 if (properties == null) {
1008 PropertyDefinition propertyDefinition;
1009 String toscaPropertyName;
1010 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
1011 toscaPropertyName = entry.getKey();
1012 propertyDefinition = new PropertyDefinition();
1013 ParameterDefinition parameterDefinition =
1014 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
1015 propertyDefinition.setType(parameterDefinition.getType());
1016 propertyDefinition.setDescription(parameterDefinition.getDescription());
1017 propertyDefinition.setRequired(parameterDefinition.getRequired());
1018 propertyDefinition.set_default(parameterDefinition.get_default());
1019 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
1020 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1021 propertyDefinition.setStatus(parameterDefinition.getStatus());
1022 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1024 return substitutionNodeTypeProperties;
1027 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
1028 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1029 Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
1030 if (attributes == null) {
1033 AttributeDefinition attributeDefinition;
1034 String toscaAttributeName;
1036 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1037 attributeDefinition = new AttributeDefinition();
1038 toscaAttributeName = entry.getKey();
1039 ParameterDefinition parameterDefinition =
1040 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1041 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1042 attributeDefinition.setType(parameterDefinition.getType());
1044 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1046 attributeDefinition.setDescription(parameterDefinition.getDescription());
1047 attributeDefinition.set_default(parameterDefinition.get_default());
1048 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1049 attributeDefinition.setStatus(parameterDefinition.getStatus());
1050 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1052 return substitutionNodeTypeAttributes;
1057 * Create and add substitution mapping to the nested substitution service template, and update
1058 * the subtitution node type accordingly with the exposed requerments and capabilities
1060 * @param context the translation context
1061 * @param substitutionNodeTypeKey the substitution node type key
1062 * @param nestedSubstitutionServiceTemplate the nested substitution service template
1063 * @param substitutionNodeType the substitution node type
1065 public static void handleSubstitutionMapping(TranslationContext context, String substitutionNodeTypeKey,
1066 ServiceTemplate nestedSubstitutionServiceTemplate,
1067 NodeType substitutionNodeType) {
1068 Map<String, Map<String, List<String>>> substitutionMapping =
1069 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType, nestedSubstitutionServiceTemplate,
1071 //add substitution mapping after capability and requirement expose calculation
1072 nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(DataModelUtil
1073 .createSubstitutionTemplateSubMapping(
1074 substitutionNodeTypeKey,
1075 substitutionNodeType,
1076 substitutionMapping));
1080 * Gets node type with flat hierarchy.
1082 * @param nodeTypeId the node type id
1083 * @param serviceTemplate the service template
1084 * @param context the context
1085 * @return the node type with flat hierarchy
1087 public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId, ServiceTemplate serviceTemplate,
1088 TranslationContext context) {
1089 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1090 ToscaServiceModel toscaServiceModel =
1091 HeatToToscaUtil.getToscaServiceModel(context, serviceTemplate.getMetadata());
1092 return (NodeType) toscaAnalyzerService.getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate,
1093 toscaServiceModel).getFlatEntity();
1098 * Create abstract substitution node template.
1100 * @param translateTo the translate to
1101 * @param templateName the template name
1102 * @param substitutionNodeTypeKey the substitution node type key
1103 * @return the abstract substitute node template
1105 public static NodeTemplate createAbstractSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1106 String substitutionNodeTypeKey) {
1107 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1108 List<String> directiveList = new ArrayList<>();
1109 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1110 substitutionNodeTemplate.setDirectives(directiveList);
1111 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1112 substitutionNodeTemplate.setProperties(
1113 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate, templateName));
1114 return substitutionNodeTemplate;
1119 * Checks if the source and target resource is a valid candidate for adding tosca dependency
1122 * @param sourceResource the source resource
1123 * @param targetResource the target resource
1124 * @param dependencyEntity the dependency entity
1125 * @return true if the candidate resources are a valid combination for the dependency relationship
1126 * and false otherwise
1128 public static boolean isValidDependsOnCandidate(Resource sourceResource, Resource targetResource,
1129 ConsolidationEntityType dependencyEntity,
1130 TranslationContext context) {
1131 dependencyEntity.setEntityType(sourceResource, targetResource, context);
1132 ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1133 ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1135 return ConsolidationTypesConnectivity.isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
1138 private static Map<String, Object> managerSubstitutionNodeTemplateProperties(TranslateTo translateTo,
1140 String templateName) {
1141 Map<String, Object> substitutionProperties = new HashMap<>();
1142 Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1143 if (Objects.nonNull(heatProperties)) {
1144 for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1145 Object property = TranslatorHeatToToscaPropertyConverter
1146 .getToscaPropertyValue(translateTo.getServiceTemplate(),
1147 translateTo.getTranslatedId(), entry.getKey(), entry.getValue(), null,
1148 translateTo.getHeatFileName(),
1149 translateTo.getHeatOrchestrationTemplate(), template,
1150 translateTo.getContext());
1151 substitutionProperties.put(entry.getKey(), property);
1154 return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1157 private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1158 Map<String, Object> substitutionProperties) {
1159 Map<String, Object> innerProps = new HashMap<>();
1160 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1161 ToscaUtil.getServiceTemplateFileName(templateName));
1162 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1163 return substitutionProperties;
1166 private static Map<String, Map<String, List<String>>> getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1167 ServiceTemplate substitutionServiceTemplate,
1168 TranslationContext context) {
1169 Map<String, NodeTemplate> nodeTemplates =
1170 substitutionServiceTemplate.getTopology_template().getNode_templates();
1171 String nodeTemplateId;
1172 NodeTemplate nodeTemplate;
1174 Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1175 if (nodeTemplates == null) {
1176 return substitutionMapping;
1179 Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1180 Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1181 substitutionMapping.put("capability", capabilitySubstitutionMapping);
1182 substitutionMapping.put("requirement", requirementSubstitutionMapping);
1183 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1184 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1185 List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1186 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition = new HashMap<>();
1187 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1188 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1189 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1191 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1192 nodeTemplateId = entry.getKey();
1193 nodeTemplate = entry.getValue();
1194 nodeType = nodeTemplate.getType();
1197 nodeTypeRequirementsDefinition = getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1198 requirementSubstitutionMapping, context);
1199 nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1200 fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1201 //set substitution node type requirements
1202 exposedRequirementsDefinition = toscaAnalyzerService
1203 .calculateExposedRequirements(nodeTypeRequirementsDefinition,
1204 nodeTemplateRequirementsAssignment);
1205 DataModelUtil.addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1209 addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping, nodeType,
1210 nodeTemplateId, substitutionServiceTemplate, context);
1213 exposedCapabilitiesDefinition = toscaAnalyzerService
1214 .calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1215 fullFilledRequirementsDefinition);
1216 DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1217 return substitutionMapping;
1220 private static void addNodeTypeCapabilitiesToSubMapping(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1221 Map<String, List<String>> capabilitySubstitutionMapping,
1222 String type, String templateName,
1223 ServiceTemplate serviceTemplate,
1224 TranslationContext context) {
1225 NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1227 if (flatNodeType.getCapabilities() != null) {
1228 flatNodeType.getCapabilities().entrySet().stream().forEach(
1229 capabilityNodeEntry -> addCapabilityToSubMapping(templateName, capabilityNodeEntry,
1230 nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping));
1234 public static boolean shouldAnnotationsToBeAdded() {
1235 return ToggleableFeature.ANNOTATIONS.isActive();
1238 private static void addCapabilityToSubMapping(String templateName,
1239 Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
1240 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1241 Map<String, List<String>> capabilitySubstitutionMapping) {
1242 String capabilityKey;
1243 List<String> capabilityMapping;
1244 capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
1245 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1246 capabilityMapping = new ArrayList<>();
1247 capabilityMapping.add(templateName);
1248 capabilityMapping.add(capabilityNodeEntry.getKey());
1249 capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1252 private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(String type, String templateName,
1253 ServiceTemplate serviceTemplate,
1254 Map<String, List<String>> requirementSubstitutionMapping,
1255 TranslationContext context) {
1256 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1257 NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1258 List<String> requirementMapping;
1260 if (flatNodeType.getRequirements() == null) {
1261 return requirementList;
1264 for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1265 for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap.entrySet()) {
1266 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1267 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil.yamlToObject(
1268 toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1269 RequirementDefinition.class);
1270 if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
1271 requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1273 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1274 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1275 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1276 requirementMapping = new ArrayList<>();
1277 requirementMapping.add(templateName);
1278 requirementMapping.add(requirementNodeEntry.getKey());
1279 requirementSubstitutionMapping
1280 .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
1281 if (Objects.isNull(requirementNodeEntryValue.getNode())) {
1282 requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1286 return requirementList;
1290 * Fetch global substitution service template service template.
1292 * @param serviceTemplate the service template
1293 * @param context the context
1294 * @return the service template
1296 public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(ServiceTemplate serviceTemplate,
1297 TranslationContext context) {
1298 ServiceTemplate globalSubstitutionServiceTemplate =
1299 context.getTranslatedServiceTemplates().get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1300 if (globalSubstitutionServiceTemplate == null) {
1301 globalSubstitutionServiceTemplate = HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1302 context.getTranslatedServiceTemplates()
1303 .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, globalSubstitutionServiceTemplate);
1305 boolean isImportAddedToServiceTemplate = DataModelUtil
1306 .isImportAddedToServiceTemplate(serviceTemplate.getImports(),
1307 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1308 if (!isImportAddedToServiceTemplate) {
1309 serviceTemplate.getImports()
1310 .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1312 return globalSubstitutionServiceTemplate;
1315 public static List<Map<String, Import>> createImportList(String templateName) {
1316 List<Map<String, Import>> imports = new ArrayList<>();
1317 Map<String, Import> importsMap = new HashMap<>();
1318 importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1319 imports.add(importsMap);
1324 * Create service template import import.
1326 * @param serviceTemplate the service template
1327 * @return the import
1329 public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1330 Import serviceTemplateImport = new Import();
1331 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1332 return serviceTemplateImport;
1336 * Create service template import import.
1338 * @param metadataTemplateName the service template name
1339 * @return the import
1341 private static Import createServiceTemplateImport(String metadataTemplateName) {
1342 Import serviceTemplateImport = new Import();
1343 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1344 return serviceTemplateImport;
1347 public static ToscaServiceModel createToscaServiceModel(ServiceTemplate entryDefinitionServiceTemplate,
1348 TranslationContext translationContext) {
1349 return new ToscaServiceModel(getCsarArtifactFiles(translationContext), getServiceTemplates(translationContext),
1350 ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1353 private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1354 FileContentHandler artifactFiles = new FileContentHandler();
1355 artifactFiles.setFiles(translationContext.getFiles());
1356 artifactFiles.setFiles(translationContext.getExternalArtifacts());
1358 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1359 heatTreeManager.createTree();
1360 ValidationStructureList validationStructureList = new ValidationStructureList(heatTreeManager.getTree());
1361 byte[] validationStructureFile =
1362 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1363 artifactFiles.addFile("HEAT.meta", validationStructureFile);
1364 return artifactFiles;
1368 private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext translationContext) {
1369 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1370 serviceTemplates.addAll(GlobalTypesGenerator.getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
1371 serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1372 Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1374 for (ServiceTemplate template : serviceTemplates) {
1375 serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1377 return serviceTemplatesMap;
1380 public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
1381 if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext()) && isSubInterfaceBoundToPort(
1383 return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
1385 return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
1388 private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
1389 return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
1392 //Method evaluate the network role from sub interface node template id, designed considering
1393 // only single sub interface present in nested file else it will return null
1394 public static Optional<String> getNetworkRoleFromSubInterfaceId(Resource resource,
1395 TranslationContext translationContext) {
1396 Optional<String> networkRole = Optional.empty();
1397 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
1399 if (!nestedHeatFileName.isPresent()) {
1403 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
1404 translationContext.getFileContent(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
1406 if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
1407 ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
1408 new ContrailV2VirtualMachineInterfaceHelper();
1409 Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
1410 nestedHeatOrchestrationTemplate.getResources().entrySet().stream()
1411 .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
1412 .isVlanSubInterfaceResource(
1413 resourceEntry.getValue()))
1415 if (vlanSubInterfaceResource.isPresent()) {
1416 Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
1417 networkRole = extractNetworkRoleFromSubInterfaceId(vlanSubInterfaceResourceEntry.getKey(),
1418 vlanSubInterfaceResourceEntry.getValue().getType());
1424 public static Optional<String> evaluateNetworkRoleFromResourceId(String resourceId, String resourceType) {
1425 Optional<PortType> portType = getPortType(resourceType);
1426 if (portType.isPresent()) {
1427 String portResourceIdRegex =
1428 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + WORDS_REGEX + UNDERSCORE + portType.get()
1430 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1431 String portIntResourceIdRegex = PORT_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
1432 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1434 String portNetworkRole = getNetworkRole(resourceId, portResourceIdRegex);
1435 String portIntNetworkRole = getNetworkRole(resourceId, portIntResourceIdRegex);
1437 return Optional.ofNullable(Objects.nonNull(portNetworkRole) ? portNetworkRole : portIntNetworkRole);
1439 return Optional.empty();
1442 private static Optional<PortType> getPortType(String resourceType) {
1444 .equals(HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
1445 return Optional.of(PortType.VMI);
1446 } else if (resourceType.equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
1447 return Optional.of(PortType.PORT);
1449 return Optional.empty();
1452 public static Optional<String> extractNetworkRoleFromSubInterfaceId(String resourceId, String resourceType) {
1453 Optional<PortType> portType = getPortType(resourceType);
1454 if (portType.isPresent()) {
1455 String subInterfaceResourceIdRegex =
1456 SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
1457 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1459 return Optional.ofNullable(getNetworkRole(resourceId, subInterfaceResourceIdRegex));
1461 return Optional.empty();
1464 private enum PortType {
1465 PORT("port"), VMI("vmi");
1467 private String portTypeName;
1469 PortType(String portTypeName) {
1470 this.portTypeName = portTypeName;
1473 public String getPortTypeName() {
1474 return portTypeName;
1478 private static String getNetworkRole(String portResourceId, String portIdRegex) {
1479 Pattern pattern = Pattern.compile(portIdRegex);
1480 Matcher matcher = pattern.matcher(portResourceId);
1481 if (matcher.matches()) {
1482 String networkRole = matcher.group(3);
1483 //Assuming network role will not contain ONLY digits
1484 if (!networkRole.matches("\\d+")) {
1485 return matcher.group(3);