2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.translator.services.heattotosca;
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.collections4.MapUtils;
21 import org.apache.commons.io.FilenameUtils;
22 import org.openecomp.core.translator.api.HeatToToscaTranslator;
23 import org.openecomp.core.translator.datatypes.TranslatorOutput;
24 import org.openecomp.core.translator.factory.HeatToToscaTranslatorFactory;
25 import org.openecomp.core.utilities.file.FileContentHandler;
26 import org.openecomp.core.utilities.file.FileUtils;
27 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
28 import org.openecomp.core.validation.util.MessageContainerUtil;
29 import org.openecomp.sdc.common.errors.CoreException;
30 import org.openecomp.sdc.common.togglz.ToggleableFeature;
31 import org.openecomp.sdc.common.utils.SdcCommon;
32 import org.openecomp.sdc.datatypes.error.ErrorLevel;
33 import org.openecomp.sdc.datatypes.error.ErrorMessage;
34 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
35 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
36 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
37 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
38 import org.openecomp.sdc.heat.datatypes.model.Resource;
39 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
40 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
41 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
42 import org.openecomp.sdc.heat.services.HeatConstants;
43 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
44 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
45 import org.openecomp.sdc.logging.api.Logger;
46 import org.openecomp.sdc.logging.api.LoggerFactory;
47 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
48 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
49 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
50 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
51 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
52 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
53 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
54 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
55 import org.openecomp.sdc.tosca.datatypes.model.Import;
56 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
57 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
58 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
59 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
60 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
61 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
62 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
63 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
64 import org.openecomp.sdc.tosca.datatypes.model.Template;
65 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
66 import org.openecomp.sdc.tosca.services.DataModelUtil;
67 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
68 import org.openecomp.sdc.tosca.services.ToscaConstants;
69 import org.openecomp.sdc.tosca.services.ToscaExtensionYamlUtil;
70 import org.openecomp.sdc.tosca.services.ToscaUtil;
71 import org.openecomp.sdc.tosca.services.YamlUtil;
72 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
73 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedPropertyVal;
74 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
75 import org.openecomp.sdc.translator.datatypes.heattotosca.ReferenceType;
76 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
77 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
78 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
79 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
80 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
81 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailV2VirtualMachineInterfaceHelper;
82 import org.openecomp.sdc.translator.services.heattotosca.helper.FunctionTranslationHelper;
83 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
84 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
86 import java.io.IOException;
87 import java.io.InputStream;
88 import java.util.ArrayList;
89 import java.util.Collection;
90 import java.util.HashMap;
91 import java.util.HashSet;
92 import java.util.List;
94 import java.util.Objects;
95 import java.util.Optional;
97 import java.util.regex.Matcher;
98 import java.util.regex.Pattern;
99 import java.util.stream.Collectors;
102 * The type Heat to tosca util.
104 public class HeatToToscaUtil {
106 private static final Logger LOGGER = LoggerFactory.getLogger(HeatToToscaUtil.class);
107 private static final String FQ_NAME = "fq_name";
108 private static final String GET_PARAM = "get_param";
109 private static final String GET_ATTR = "get_attr";
110 private static final String GET_RESOURCE = "get_resource";
111 private static final String UNDERSCORE = "_";
112 private static final String PORT_RESOURCE_ID_REGEX_SUFFIX = "(_\\d)*";
113 private static final String PORT_RESOURCE_ID_REGEX_PREFIX =
114 "(\\w+)" + PORT_RESOURCE_ID_REGEX_SUFFIX;
115 private static final String PORT_INT_RESOURCE_ID_REGEX_PREFIX =
116 PORT_RESOURCE_ID_REGEX_PREFIX + "_" + "int_(\\w+)_";
119 * Load and translate template data translator output.
121 * @param fileNameContentMap the file name content map
122 * @return the translator output
124 public static TranslatorOutput loadAndTranslateTemplateData(
125 FileContentHandler fileNameContentMap) {
126 HeatToToscaTranslator heatToToscaTranslator =
127 HeatToToscaTranslatorFactory.getInstance().createInterface();
129 try (InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME)) {
130 heatToToscaTranslator
131 .addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
132 } catch (IOException e) {
133 throw new RuntimeException("Failed to read manifest", e);
136 fileNameContentMap.getFileList().stream()
137 .filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME))).forEach(
138 fileName -> heatToToscaTranslator
139 .addFile(fileName, FileUtils.toByteArray
140 (fileNameContentMap.getFileContent(fileName))));
142 Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
143 if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
144 TranslatorOutput translatorOutput = new TranslatorOutput();
145 translatorOutput.setErrorMessages(errors);
146 return translatorOutput;
149 try (InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap)) {
150 heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
151 return heatToToscaTranslator.translate();
152 } catch (IOException e) {
153 // rethrow as a RuntimeException to keep the signature backward compatible
154 throw new RuntimeException("Failed to read Heat template tree", e);
159 private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
160 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
161 heatTreeManager.createTree();
162 HeatStructureTree tree = heatTreeManager.getTree();
163 ValidationStructureList validationStructureList = new ValidationStructureList(tree);
164 return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
168 * Build list of files to search optional.
170 * @param heatFileName the heat file name
171 * @param filesDataList the files data list
172 * @param types the types
173 * @return the optional
175 public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
176 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))
196 .collect(Collectors.toList());
200 * Gets file data from the list according to the input heat file name.
202 * @param heatFileName the heat file name
203 * @param fileDataList the file data list
204 * @return the file data
206 public static Optional<FileData> getFileData(String heatFileName,
207 Collection<FileData> fileDataList) {
208 for (FileData file : fileDataList) {
209 if (file.getFile().equals(heatFileName)) {
210 return Optional.of(file);
213 return Optional.empty();
217 * Gets file data which is supported by the translator, from the context according the input heat
220 * @param heatFileName the heat file name
221 * @param context the translation context
222 * @return the file data
224 public static FileData getFileData(String heatFileName, TranslationContext context) {
225 List<FileData> fileDataList = context.getManifest().getContent().getData();
226 for (FileData fileData : fileDataList) {
227 if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType())
228 && fileData.getFile().equals(heatFileName)) {
235 static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList,
236 Set<FileData.Type> typeFilter,
237 TranslationContext translationContext) {
238 FileDataCollection fileDataCollection = new FileDataCollection();
239 Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
240 Set<String> referenced = new HashSet<>();
242 for (FileData fileData : filteredFiles.values()) {
243 String fileName = fileData.getFile();
245 if (FileData.isHeatFile(fileData.getType())) {
246 if (fileData.getBase() != null && fileData.getBase()) {
247 fileDataCollection.addBaseFiles(fileData);
249 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
250 .yamlToObject(translationContext.getFileContent(fileName),
251 HeatOrchestrationTemplate.class);
252 if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
253 applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext,
254 fileDataCollection, filteredFiles, referenced);
258 fileDataCollection.addArtifactFiles(fileData);
259 filteredFiles.remove(fileData.getFile());
263 referenced.forEach(filteredFiles::remove);
264 if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
265 for (FileData fileData : fileDataCollection.getBaseFile()) {
266 filteredFiles.remove(fileData.getFile());
269 fileDataCollection.setAddOnFiles(filteredFiles.values());
270 return fileDataCollection;
273 private static void applyFilterOnFileCollection(
274 HeatOrchestrationTemplate heatOrchestrationTemplate,
275 TranslationContext translationContext,
276 FileDataCollection fileDataCollection, Map<String, FileData> filteredFiles,
277 Set<String> referenced) {
278 List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
280 for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
281 if (filenames.contains(resource.getType())) {
282 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
284 } else if (resource.getType()
285 .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
286 handleResourceGrpNestedFile(resource, translationContext, fileDataCollection,
287 filteredFiles, filenames, referenced);
292 private static void handleResourceGrpNestedFile(Resource resource,
293 TranslationContext translationContext,
294 FileDataCollection fileDataCollection,
295 Map<String, FileData> filteredFiles,
296 List<String> filenames,
297 Set<String> referenced) {
298 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
299 Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
300 if (innerTypeDef instanceof String) {
301 String internalResourceType = (String) innerTypeDef;
302 if (filenames.contains(internalResourceType)) {
303 handleNestedFile(translationContext, fileDataCollection, filteredFiles,
304 referenced, internalResourceType);
309 private static void handleNestedFile(TranslationContext translationContext,
310 FileDataCollection fileDataCollection,
311 Map<String, FileData> filteredFiles, Set<String> referenced,
312 String nestedFileName) {
313 referenced.add(nestedFileName);
314 fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
315 translationContext.getNestedHeatsFiles().add(nestedFileName);
318 private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
319 Set<FileData.Type> typesToGet) {
320 Map<String, FileData> filtered = new HashMap<>();
321 fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
322 .forEach(file -> filtered.put(file.getFile(), file));
326 private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
327 return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
331 * Extract attached resource id optional.
333 * @param translateTo the translate to
334 * @param propertyName the property name
335 * @return the optional
337 public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
338 String propertyName) {
339 Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
340 if (propertyValue == null) {
341 return Optional.empty();
343 return extractAttachedResourceId(translateTo.getHeatFileName(),
344 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(), propertyValue);
348 * Extract attached resource id optional.
350 * @param heatFileName the heat file name
351 * @param heatOrchestrationTemplate the heat orchestration template
352 * @param context the context
353 * @param propertyValue the property value
354 * @return the optional
356 public static Optional<AttachedResourceId> extractAttachedResourceId(
358 HeatOrchestrationTemplate heatOrchestrationTemplate,
359 TranslationContext context,
360 Object propertyValue) {
365 if (Objects.isNull(propertyValue)) {
366 return Optional.empty();
369 ReferenceType referenceType = ReferenceType.OTHER;
370 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
371 Map<String, Object> propMap = (Map) propertyValue;
372 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
373 entity = entry.getValue();
374 String key = entry.getKey();
375 referenceType = getReferenceTypeFromAttachedResouce(key);
377 if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
380 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
381 .translateFunction(null, null, null, entry.getKey(), entry.getValue(), heatFileName,
382 heatOrchestrationTemplate, null, context);
384 if (translatedId instanceof String
385 && !FunctionTranslationHelper.isResourceSupported((String) translatedId)) {
390 translatedId = propertyValue;
391 entity = propertyValue;
394 return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
397 private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
398 ReferenceType referenceType;
401 referenceType = ReferenceType.GET_RESOURCE;
404 referenceType = ReferenceType.GET_PARAM;
407 referenceType = ReferenceType.GET_ATTR;
410 referenceType = ReferenceType.OTHER;
414 return referenceType;
418 * Gets contrail attached heat resource id.
420 * @param attachedResource the attached resource
421 * @return the contrail attached heat resource id
423 public static Optional<String> getContrailAttachedHeatResourceId(
424 AttachedResourceId attachedResource) {
425 if (attachedResource == null) {
426 return Optional.empty();
429 if (attachedResource.isGetResource()) {
430 return Optional.of((String) attachedResource.getEntityId());
433 if (attachedResource.isGetAttr()) {
434 return getResourceId(attachedResource.getEntityId());
436 return Optional.empty();
440 * Extract property optional.
442 * @param propertyValue the property value
443 * @return the optional
445 private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
446 Object attachedPropertyVal;
447 if (Objects.isNull(propertyValue)) {
448 return Optional.empty();
451 ReferenceType referenceType = ReferenceType.OTHER;
452 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
453 Map<String, Object> propMap = (Map) propertyValue;
454 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
455 attachedPropertyVal = entry.getValue();
456 String key = entry.getKey();
459 referenceType = ReferenceType.GET_RESOURCE;
462 referenceType = ReferenceType.GET_PARAM;
465 referenceType = ReferenceType.GET_ATTR;
472 attachedPropertyVal = propertyValue;
474 return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
480 * @param nodeTemplate the node template
481 * @param propertyKey the property key
483 public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
484 Object value = nodeTemplate.getProperties().get(propertyKey);
485 if (value != null && !(value instanceof Map)) {
486 nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
493 * @param nodeTemplate the node template
494 * @param propertyListKey the property list key
496 public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
497 Object listValue = nodeTemplate.getProperties().get(propertyListKey);
498 if (listValue instanceof List) {
499 List booleanList = (List) listValue;
500 for (int i = 0; i < booleanList.size(); i++) {
501 Object value = booleanList.get(i);
502 if (value != null && !(value instanceof Map)) {
503 booleanList.set(i, HeatBoolean.eval(value));
511 * Is yml file type boolean.
513 * @param filename the filename
514 * @return the boolean
516 public static boolean isYmlFileType(String filename) {
517 String extension = FilenameUtils.getExtension(filename);
518 return "yaml".equalsIgnoreCase(extension)
519 || "yml".equalsIgnoreCase(extension);
523 * Is nested resource boolean.
525 * @param resource the resource
526 * @return the boolean
528 public static boolean isNestedResource(Resource resource) {
529 String resourceType = resource.getType();
531 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
532 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
533 if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof
535 //currently only resource group which is poinitng to nested heat file is supported
536 //dynamic type is currently not supported
539 String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
540 .RESOURCE_DEF_TYPE_PROPERTY_NAME);
541 if (isYamlFile(internalResourceType)) {
544 } else if (isYamlFile(resourceType)) {
551 * Checks if the current HEAT resource if of type sub interface.
553 * @param resource the resource
554 * @return true if the resource is of sub interface type and false otherwise
556 public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
557 if (!ToggleableFeature.VLAN_TAGGING.isActive()) {
558 //Remove this once feature is stable and moved to production
561 //Check if resource group is a nested resource
562 if (!isNestedResource(resource)) {
565 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
566 return nestedHeatFileName.filter(fileName ->
567 isNestedVlanResource(fileName, context)).isPresent();
570 private static boolean isNestedVlanResource(String nestedHeatFileName,
571 TranslationContext translationContext) {
572 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
573 .yamlToObject(translationContext.getFileContent(nestedHeatFileName),
574 HeatOrchestrationTemplate.class);
575 return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())
576 && nestedHeatOrchestrationTemplate.getResources().values().stream()
577 .anyMatch(new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
580 public static Optional<String> getSubInterfaceParentPortNodeTemplateId(
581 TranslateTo subInterfaceTo) {
582 String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
583 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
584 .yamlToObject(subInterfaceTo.getContext().getFileContent(subInterfaceResourceType),
585 HeatOrchestrationTemplate.class);
586 if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
587 return Optional.empty();
589 for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate
590 .getResources().entrySet()) {
591 Resource resource = resourceEntry.getValue();
592 if (isVmiRefsPropertyExists(resource)) {
593 Object toscaPropertyValue =
594 TranslatorHeatToToscaPropertyConverter
595 .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
596 resourceEntry.getKey(), HeatConstants.VMI_REFS_PROPERTY_NAME,
597 resource.getProperties().get(HeatConstants.VMI_REFS_PROPERTY_NAME),
598 resource.getType(), subInterfaceResourceType, nestedHeatOrchestrationTemplate,
599 null, subInterfaceTo.getContext());
600 return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
603 return Optional.empty();
606 private static boolean isVmiRefsPropertyExists(Resource resource) {
607 return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
608 .getHeatResource().equals(resource.getType())
609 && MapUtils.isNotEmpty(resource.getProperties())
610 && resource.getProperties().containsKey(HeatConstants.VMI_REFS_PROPERTY_NAME);
613 public static String getSubInterfaceResourceType(Resource resource) {
614 if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
615 return ((Map) resource.getProperties()
616 .get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
617 .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME)
620 return resource.getType();
623 private static Optional<String> getParentNodeTemplateIdFromPropertyValue(
624 Object toscaPropertyValue,
625 TranslateTo subInterfaceTo) {
626 if (toscaPropertyValue instanceof List
627 && ((List) toscaPropertyValue).get(0) instanceof Map) {
628 Resource subInterfaceResource = subInterfaceTo.getResource();
629 Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
630 String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT
632 Map<String, Object> resourceDefPropertiesMap;
633 if (!isYamlFile(subInterfaceResource.getType())) {
634 resourceDefPropertiesMap = (Map) ((Map) subInterfaceResource
635 .getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
636 .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
638 resourceDefPropertiesMap = subInterfaceResource.getProperties();
640 Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
641 if (parentPortObj instanceof Map) {
642 Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
643 if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions
644 .GET_RESOURCE.getFunction())) {
645 return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
646 subInterfaceTo.getHeatOrchestrationTemplate(),
647 parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
648 subInterfaceTo.getContext());
652 return Optional.empty();
656 * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
657 * least one or more compute nodes).
659 * @param resource the resource
660 * @param context the context
661 * @return true if the resource represents a VFC and false otherwise.
663 public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
664 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
665 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
666 .yamlToObject(context.getFileContent(nestedHeatFileName.get()),
667 HeatOrchestrationTemplate.class);
668 if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
669 for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
670 if (ConsolidationDataUtil
671 .isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
680 * Get nested heat file name in case of nested resource.
682 * @param resource the resource
683 * @return the nested heat file name
685 private static Optional<String> getNestedHeatFileName(Resource resource) {
686 if (!isNestedResource(resource)) {
687 return Optional.empty();
690 String resourceType = resource.getType();
692 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
693 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
694 String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
695 .RESOURCE_DEF_TYPE_PROPERTY_NAME);
696 return Optional.of(internalResourceType);
698 return Optional.of(resourceType);
704 * @param resource the resource
705 * @return the nested file
707 public static Optional<String> getNestedFile(Resource resource) {
708 if (!isNestedResource(resource)) {
709 return Optional.empty();
711 String resourceType = resource.getType();
712 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
713 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
714 String internalResourceType = (String) ((Map) resourceDef).get(HeatConstants
715 .RESOURCE_DEF_TYPE_PROPERTY_NAME);
716 return Optional.of(internalResourceType);
718 return Optional.of(resourceType);
722 public static boolean isYamlFile(String fileName) {
723 return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
729 * @param heatOrchestrationTemplate the heat orchestration template
730 * @param resourceId the resource id
731 * @param heatFileName the heat file name
732 * @return the resource
734 public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate,
735 String resourceId, String heatFileName) {
736 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
737 if (resource == null) {
738 throw new CoreException(
739 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
748 * @param resourceId the resource id
749 * @param heatOrchestrationTemplate heat orchestration template
750 * @param heatFileName heat file name
751 * @return resource type
753 public static String getResourceType(String resourceId,
754 HeatOrchestrationTemplate heatOrchestrationTemplate,
755 String heatFileName) {
756 return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName)
761 * Is heat file nested boolean.
763 * @param translateTo the translate to
764 * @param heatFileName the heat file name
765 * @return the boolean
767 public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
768 return isHeatFileNested(translateTo.getContext(), heatFileName);
771 public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
772 return context.getNestedHeatsFiles().contains(heatFileName);
776 * Extract contrail get resource attached heat resource id optional.
778 * @param propertyValue the property value
779 * @return the optional
781 public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(
782 Object propertyValue) {
783 if (propertyValue instanceof Map) {
784 if (((Map) propertyValue).containsKey(GET_ATTR)) {
785 return getResourceId(((Map) propertyValue).get(GET_ATTR));
786 } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
787 return getHeatResourceIdFromResource((Map) propertyValue);
789 Collection valCollection = ((Map) propertyValue).values();
790 return evaluateHeatResourceId(valCollection);
792 } else if (propertyValue instanceof List) {
793 return evaluateHeatResourceId((List) propertyValue);
795 return Optional.empty();
798 private static Optional<String> getResourceId(Object data) {
799 if (data instanceof List && CollectionUtils.size(data) > 1
800 && FQ_NAME.equals(((List) data).get(1))
801 && ((List) data).get(0) instanceof String) {
802 return Optional.of((String) ((List) data).get(0));
804 LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
805 return Optional.empty();
809 private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
810 Object value = propertyValue.get(GET_RESOURCE);
811 if (value instanceof String) {
812 return Optional.of((String) value);
814 LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
815 return Optional.empty();
819 private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
820 for (Object prop : propertyValue) {
821 Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
822 if (ret.isPresent()) {
826 return Optional.empty();
830 * Gets tosca service model.
832 * @param context translation context
833 * @return the tosca service model
835 public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
836 Map<String, String> metadata = new HashMap<>();
837 metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
838 return getToscaServiceModel(context, metadata);
842 * Gets tosca service model.
844 * @param context translation context
845 * @param entryDefinitionMetadata template name of the entry definition servie template
846 * @return the tosca service model
848 private static ToscaServiceModel getToscaServiceModel(
849 TranslationContext context,
850 Map<String, String> entryDefinitionMetadata) {
851 Map<String, ServiceTemplate> serviceTemplates =
852 new HashMap<>(context.getGlobalServiceTemplates());
853 Collection<ServiceTemplate> tmpServiceTemplates =
854 context.getTranslatedServiceTemplates().values();
855 for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
856 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
858 return new ToscaServiceModel(null, serviceTemplates,
859 ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
863 * Gets service template from context.
865 * @param serviceTemplateFileName the service template file name
866 * @param context the context
867 * @return the service template from context
869 public static Optional<ServiceTemplate> getServiceTemplateFromContext(
870 String serviceTemplateFileName, TranslationContext context) {
871 for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
872 if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
873 return Optional.of(serviceTemplate);
876 return Optional.empty();
880 * Adding link requerment from port node template to network node template.
882 * @param portNodeTemplate port node template
883 * @param networkTranslatedId network node template id
885 public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
886 String networkTranslatedId) {
887 RequirementAssignment requirement = new RequirementAssignment();
888 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
889 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
890 requirement.setNode(networkTranslatedId);
891 DataModelUtil.addRequirementAssignment(portNodeTemplate,
892 ToscaConstants.LINK_REQUIREMENT_ID, requirement);
897 * Adding binding requerment from sub interface node template to interface (port) node template.
899 * @param subInterfaceNodeTemplate sub interface template
900 * @param interfaceTranslatedId interface node template id
902 public static void addBindingReqFromSubInterfaceToInterface(
903 NodeTemplate subInterfaceNodeTemplate, String interfaceTranslatedId) {
904 RequirementAssignment requirement = new RequirementAssignment();
905 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
906 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
907 requirement.setNode(interfaceTranslatedId);
909 .addRequirementAssignment(subInterfaceNodeTemplate,
910 ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
914 * Get property Parameter Name Value.
916 * @param property property
917 * @return Parameter name in case the property include "get_param" function
919 public static Optional<String> getPropertyParameterNameValue(Object property) {
920 if (Objects.isNull(property)) {
921 return Optional.empty();
923 Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
924 if (extractedProperty.isPresent()) {
925 return getParameterName(extractedProperty.get());
927 return Optional.empty();
930 private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
931 if (!extractedProperty.isGetParam()) {
932 return Optional.empty();
934 Object getParamFuncValue = extractedProperty.getPropertyValue();
935 if (getParamFuncValue instanceof String) {
936 return Optional.of((String) getParamFuncValue);
938 return Optional.of((String) ((List) getParamFuncValue).get(0));
942 public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
943 String heatPropertyName) {
944 return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
948 * Gets tosca property name.
950 * @param translateTo the translate to
951 * @param heatPropertyName the heat property name
952 * @return the tosca property name
954 public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
955 return translateTo.getContext()
956 .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
960 * Gets tosca attribute name.
962 * @param context the context
963 * @param heatResourceType the heat resource type
964 * @param heatAttrName the heat attr name
965 * @return the tosca attribute name
967 public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
968 String heatAttrName) {
969 return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
973 * Gets tosca attribute name.
975 * @param translateTo the translate to
976 * @param heatAttrName the heat attr name
977 * @return the tosca attribute name
979 public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
980 return translateTo.getContext()
981 .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
985 * Create init substitution service template service template.
987 * @param templateName the template name
988 * @return the service template
990 public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
991 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
992 Map<String, String> templateMetadata = new HashMap<>();
993 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
994 nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
995 nestedSubstitutionServiceTemplate
996 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
997 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
998 List<Map<String, Import>> globalTypesImportList =
999 GlobalTypesGenerator.getGlobalTypesImportList();
1000 globalTypesImportList.addAll(
1001 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1002 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
1003 return nestedSubstitutionServiceTemplate;
1007 * Create init global substitution service template service template.
1009 * @return the service template
1011 private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
1012 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
1013 Map<String, String> templateMetadata = new HashMap<>();
1014 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
1015 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1016 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
1017 globalSubstitutionServiceTemplate
1018 .setImports(GlobalTypesGenerator.getGlobalTypesImportList());
1019 globalSubstitutionServiceTemplate
1020 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
1021 return globalSubstitutionServiceTemplate;
1025 * Create substitution node type node type.
1027 * @param substitutionServiceTemplate the substitution service template
1028 * @return the node type
1030 public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
1031 NodeType substitutionNodeType = new NodeType();
1032 substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
1033 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
1034 substitutionNodeType
1035 .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
1036 substitutionNodeType
1037 .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
1038 return substitutionNodeType;
1041 private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
1042 ServiceTemplate substitutionServiceTemplate) {
1043 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
1044 Map<String, ParameterDefinition> properties =
1045 substitutionServiceTemplate.getTopology_template().getInputs();
1046 if (properties == null) {
1050 PropertyDefinition propertyDefinition;
1051 String toscaPropertyName;
1052 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
1053 toscaPropertyName = entry.getKey();
1054 propertyDefinition = new PropertyDefinition();
1055 ParameterDefinition parameterDefinition =
1056 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
1057 propertyDefinition.setType(parameterDefinition.getType());
1058 propertyDefinition.setDescription(parameterDefinition.getDescription());
1059 propertyDefinition.setRequired(parameterDefinition.getRequired());
1060 propertyDefinition.set_default(parameterDefinition.get_default());
1061 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
1062 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1063 propertyDefinition.setStatus(parameterDefinition.getStatus());
1064 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1066 return substitutionNodeTypeProperties;
1069 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
1070 ServiceTemplate substitutionServiceTemplate) {
1071 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1072 Map<String, ParameterDefinition> attributes =
1073 substitutionServiceTemplate.getTopology_template().getOutputs();
1074 if (attributes == null) {
1077 AttributeDefinition attributeDefinition;
1078 String toscaAttributeName;
1080 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1081 attributeDefinition = new AttributeDefinition();
1082 toscaAttributeName = entry.getKey();
1083 ParameterDefinition parameterDefinition =
1084 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1085 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1086 attributeDefinition.setType(parameterDefinition.getType());
1088 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1090 attributeDefinition.setDescription(parameterDefinition.getDescription());
1091 attributeDefinition.set_default(parameterDefinition.get_default());
1092 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1093 attributeDefinition.setStatus(parameterDefinition.getStatus());
1094 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1096 return substitutionNodeTypeAttributes;
1101 * Create and add substitution mapping to the nested substitution service template, and update
1102 * the subtitution node type accordingly with the exposed requerments and capabilities
1104 * @param context the translation context
1105 * @param substitutionNodeTypeKey the substitution node type key
1106 * @param nestedSubstitutionServiceTemplate the nested substitution service template
1107 * @param substitutionNodeType the substitution node type
1109 public static void handleSubstitutionMapping(
1110 TranslationContext context,
1111 String substitutionNodeTypeKey,
1112 ServiceTemplate nestedSubstitutionServiceTemplate,
1113 NodeType substitutionNodeType) {
1114 Map<String, Map<String, List<String>>> substitutionMapping =
1115 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
1116 nestedSubstitutionServiceTemplate, context);
1117 //add substitution mapping after capability and requirement expose calculation
1118 nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
1119 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeKey,
1120 substitutionNodeType, substitutionMapping));
1124 * Gets node type with flat hierarchy.
1126 * @param nodeTypeId the node type id
1127 * @param serviceTemplate the service template
1128 * @param context the context
1129 * @return the node type with flat hierarchy
1131 public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId,
1132 ServiceTemplate serviceTemplate,
1133 TranslationContext context) {
1134 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1135 ToscaServiceModel toscaServiceModel = HeatToToscaUtil
1136 .getToscaServiceModel(context, serviceTemplate.getMetadata());
1137 return (NodeType) toscaAnalyzerService
1138 .getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate, toscaServiceModel);
1142 * Create substitution node template node template.
1144 * @param translateTo the translate to
1145 * @param templateName the template name
1146 * @param substitutionNodeTypeKey the substitution node type key
1147 * @return the node template
1149 public NodeTemplate createSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1150 String substitutionNodeTypeKey) {
1151 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1152 List<String> directiveList = new ArrayList<>();
1153 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1154 substitutionNodeTemplate.setDirectives(directiveList);
1155 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1156 substitutionNodeTemplate.setProperties(
1157 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
1159 return substitutionNodeTemplate;
1163 * Create abstract substitution node template.
1165 * @param translateTo the translate to
1166 * @param templateName the template name
1167 * @param substitutionNodeTypeKey the substitution node type key
1168 * @return the abstract substitute node template
1170 public static NodeTemplate createAbstractSubstitutionNodeTemplate(
1171 TranslateTo translateTo,
1172 String templateName,
1173 String substitutionNodeTypeKey) {
1174 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1175 List<String> directiveList = new ArrayList<>();
1176 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1177 substitutionNodeTemplate.setDirectives(directiveList);
1178 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1179 substitutionNodeTemplate.setProperties(
1180 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
1182 return substitutionNodeTemplate;
1187 * Checks if the source and target resource is a valid candidate for adding tosca dependency
1190 * @param sourceResource the source resource
1191 * @param targetResource the target resource
1192 * @param dependencyEntity the dependency entity
1193 * @return true if the candidate resources are a valid combination for the dependency relationship
1194 * and false otherwise
1196 public static boolean isValidDependsOnCandidate(Resource sourceResource,
1197 Resource targetResource,
1198 ConsolidationEntityType dependencyEntity,
1199 TranslationContext context) {
1200 dependencyEntity.setEntityType(sourceResource, targetResource, context);
1201 ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1202 ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1204 return ConsolidationTypesConnectivity
1205 .isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
1208 private static Map<String, Object> managerSubstitutionNodeTemplateProperties(
1209 TranslateTo translateTo,
1211 String templateName) {
1212 Map<String, Object> substitutionProperties = new HashMap<>();
1213 Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1214 if (Objects.nonNull(heatProperties)) {
1215 for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1216 Object property = TranslatorHeatToToscaPropertyConverter
1217 .getToscaPropertyValue(translateTo.getServiceTemplate(),
1218 translateTo.getTranslatedId(), entry.getKey(),
1219 entry.getValue(), null, translateTo.getHeatFileName(),
1220 translateTo.getHeatOrchestrationTemplate(), template, translateTo.getContext());
1221 substitutionProperties.put(entry.getKey(), property);
1224 return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1227 private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1229 substitutionProperties) {
1230 Map<String, Object> innerProps = new HashMap<>();
1231 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1232 ToscaUtil.getServiceTemplateFileName(templateName));
1233 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1234 return substitutionProperties;
1237 private static Map<String, Map<String, List<String>>>
1238 getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1239 ServiceTemplate substitutionServiceTemplate,
1240 TranslationContext context) {
1241 Map<String, NodeTemplate> nodeTemplates =
1242 substitutionServiceTemplate.getTopology_template().getNode_templates();
1243 String nodeTemplateId;
1244 NodeTemplate nodeTemplate;
1246 Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1247 if (nodeTemplates == null) {
1248 return substitutionMapping;
1251 Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1252 Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1253 substitutionMapping.put("capability", capabilitySubstitutionMapping);
1254 substitutionMapping.put("requirement", requirementSubstitutionMapping);
1255 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1256 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1257 List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1258 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition =
1260 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1261 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1262 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1264 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1265 nodeTemplateId = entry.getKey();
1266 nodeTemplate = entry.getValue();
1267 nodeType = nodeTemplate.getType();
1270 nodeTypeRequirementsDefinition =
1271 getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1272 requirementSubstitutionMapping, context);
1273 nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1274 fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1275 //set substitution node type requirements
1276 exposedRequirementsDefinition =
1277 toscaAnalyzerService.calculateExposedRequirements(nodeTypeRequirementsDefinition,
1278 nodeTemplateRequirementsAssignment);
1280 .addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1284 addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition,
1285 capabilitySubstitutionMapping, nodeType,
1286 nodeTemplateId, substitutionServiceTemplate, context);
1289 exposedCapabilitiesDefinition =
1290 toscaAnalyzerService.calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1291 fullFilledRequirementsDefinition);
1292 DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1293 return substitutionMapping;
1296 private static void addNodeTypeCapabilitiesToSubMapping(
1297 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1298 Map<String, List<String>> capabilitySubstitutionMapping, String type, String templateName,
1299 ServiceTemplate serviceTemplate, TranslationContext context) {
1300 NodeType flatNodeType =
1301 getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1303 if (flatNodeType.getCapabilities() != null) {
1304 flatNodeType.getCapabilities()
1307 .forEach(capabilityNodeEntry ->
1308 addCapabilityToSubMapping(
1309 templateName, capabilityNodeEntry, nodeTypeCapabilitiesDefinition,
1310 capabilitySubstitutionMapping));
1314 public static boolean shouldAnnotationsToBeAdded() {
1315 return ToggleableFeature.ANNOTATIONS.isActive();
1318 private static void addCapabilityToSubMapping(String templateName,
1319 Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
1320 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1321 Map<String, List<String>> capabilitySubstitutionMapping) {
1322 String capabilityKey;
1323 List<String> capabilityMapping;
1324 capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
1325 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1326 capabilityMapping = new ArrayList<>();
1327 capabilityMapping.add(templateName);
1328 capabilityMapping.add(capabilityNodeEntry.getKey());
1329 capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1332 private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(
1334 String templateName,
1335 ServiceTemplate serviceTemplate,
1336 Map<String, List<String>> requirementSubstitutionMapping,
1337 TranslationContext context) {
1338 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1339 NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1340 List<String> requirementMapping;
1342 if (flatNodeType.getRequirements() == null) {
1343 return requirementList;
1346 for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1347 for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap
1349 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1350 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil
1351 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1352 RequirementDefinition.class);
1353 if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
1354 requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
1356 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1357 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1358 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1359 requirementMapping = new ArrayList<>();
1360 requirementMapping.add(templateName);
1361 requirementMapping.add(requirementNodeEntry.getKey());
1362 requirementSubstitutionMapping
1363 .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
1364 if (Objects.isNull(requirementNodeEntryValue.getNode())) {
1365 requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
1369 return requirementList;
1373 * Fetch global substitution service template service template.
1375 * @param serviceTemplate the service template
1376 * @param context the context
1377 * @return the service template
1379 public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(
1380 ServiceTemplate serviceTemplate,
1381 TranslationContext context) {
1382 ServiceTemplate globalSubstitutionServiceTemplate =
1383 context.getTranslatedServiceTemplates()
1384 .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1385 if (globalSubstitutionServiceTemplate == null) {
1386 globalSubstitutionServiceTemplate =
1387 HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1388 context.getTranslatedServiceTemplates()
1389 .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
1390 globalSubstitutionServiceTemplate);
1392 boolean isImportAddedToServiceTemplate =
1393 DataModelUtil.isImportAddedToServiceTemplate(serviceTemplate.getImports(), Constants
1394 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1395 if (!isImportAddedToServiceTemplate) {
1396 serviceTemplate.getImports()
1398 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1400 return globalSubstitutionServiceTemplate;
1403 public static List<Map<String, Import>> createImportList(String templateName) {
1404 List<Map<String, Import>> imports = new ArrayList<>();
1405 Map<String, Import> importsMap = new HashMap<>();
1406 importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1407 imports.add(importsMap);
1412 * Create service template import import.
1414 * @param serviceTemplate the service template
1415 * @return the import
1417 public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1418 Import serviceTemplateImport = new Import();
1419 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1420 return serviceTemplateImport;
1424 * Create service template import import.
1426 * @param metadataTemplateName the service template name
1427 * @return the import
1429 private static Import createServiceTemplateImport(String metadataTemplateName) {
1430 Import serviceTemplateImport = new Import();
1431 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1432 return serviceTemplateImport;
1435 public static ToscaServiceModel createToscaServiceModel(ServiceTemplate
1436 entryDefinitionServiceTemplate,
1437 TranslationContext translationContext) {
1438 return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
1439 getServiceTemplates(translationContext),
1440 ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1443 private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1444 FileContentHandler artifactFiles = new FileContentHandler();
1445 artifactFiles.setFiles(translationContext.getFiles());
1446 artifactFiles.setFiles(translationContext.getExternalArtifacts());
1448 HeatTreeManager heatTreeManager =
1449 HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1450 heatTreeManager.createTree();
1451 ValidationStructureList validationStructureList =
1452 new ValidationStructureList(heatTreeManager.getTree());
1453 byte[] validationStructureFile =
1454 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1455 artifactFiles.addFile("HEAT.meta", validationStructureFile);
1456 return artifactFiles;
1460 private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext
1461 translationContext) {
1462 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1463 serviceTemplates.addAll(GlobalTypesGenerator
1464 .getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
1465 serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1466 Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1468 for (ServiceTemplate template : serviceTemplates) {
1469 serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1471 return serviceTemplatesMap;
1474 public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
1475 if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext())
1476 && isSubInterfaceBoundToPort(translateTo)) {
1477 return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
1479 return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
1482 private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
1483 return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
1486 //Method evaluate the network role from sub interface node template id, designed considering
1487 // only single sub interface present in nested file else it will return null
1488 public static Optional<String> getNetworkRoleFromResource(Resource resource,
1489 TranslationContext translationContext) {
1490 Optional<String> networkRole = Optional.empty();
1491 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
1493 if (!nestedHeatFileName.isPresent()) {
1497 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
1498 .yamlToObject(translationContext.getFileContent(nestedHeatFileName.get()),
1499 HeatOrchestrationTemplate.class);
1501 if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
1502 ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
1503 new ContrailV2VirtualMachineInterfaceHelper();
1504 Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
1505 nestedHeatOrchestrationTemplate
1506 .getResources().entrySet().stream()
1507 .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
1508 .isVlanSubInterfaceResource(resourceEntry.getValue()))
1510 if (vlanSubInterfaceResource.isPresent()) {
1511 Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
1512 networkRole = evaluateNetworkRoleFromResourceId(vlanSubInterfaceResourceEntry.getKey(),
1513 vlanSubInterfaceResourceEntry.getValue().getType());
1519 public static Optional<String> evaluateNetworkRoleFromResourceId(String resourceId,
1520 String resourceType) {
1521 if (resourceType.equals(
1522 HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
1523 return Optional.ofNullable(extractNetworkRoleFromPortId(resourceId, PortType.VMI));
1526 if (resourceType.equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
1527 return Optional.ofNullable(extractNetworkRoleFromPortId
1528 (resourceId, PortType.PORT));
1530 return Optional.empty();
1533 private static String extractNetworkRoleFromPortId(String portResourceId, PortType portType) {
1534 String portResourceIdRegex =
1535 PORT_RESOURCE_ID_REGEX_PREFIX + "_(\\w+)_" + portType.getPortTypeName() +
1536 PORT_RESOURCE_ID_REGEX_SUFFIX;
1537 String portIntResourceIdRegex =
1538 PORT_INT_RESOURCE_ID_REGEX_PREFIX + portType.getPortTypeName() +
1539 PORT_RESOURCE_ID_REGEX_SUFFIX;
1541 String portNetworkRole = getPortNetworkRole(portResourceId, portResourceIdRegex);
1542 String portIntNetworkRole = getPortNetworkRole(portResourceId, portIntResourceIdRegex);
1544 return Objects.nonNull(portNetworkRole) ? portNetworkRole : portIntNetworkRole;
1547 private enum PortType {
1551 private String portTypeName;
1553 PortType(String portTypeName) {
1554 this.portTypeName = portTypeName;
1557 public String getPortTypeName() {
1558 return portTypeName;
1562 private static String getPortNetworkRole(String portResourceId, String portIdRegex) {
1563 Pattern pattern = Pattern.compile(portIdRegex);
1564 Matcher matcher = pattern.matcher(portResourceId);
1565 if (matcher.matches()) {
1566 String networkRole = matcher.group(3);
1567 //Assuming network role will not contain ONLY digits
1568 if (!networkRole.matches("\\d+")) {
1569 return matcher.group(3);