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.utils.SdcCommon;
63 import org.openecomp.sdc.datatypes.error.ErrorLevel;
64 import org.openecomp.sdc.datatypes.error.ErrorMessage;
65 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
66 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
67 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
68 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
69 import org.openecomp.sdc.heat.datatypes.model.Resource;
70 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
71 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
72 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
73 import org.openecomp.sdc.heat.services.HeatConstants;
74 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
75 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
76 import org.openecomp.sdc.logging.api.Logger;
77 import org.openecomp.sdc.logging.api.LoggerFactory;
78 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
79 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
80 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
81 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
82 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
83 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
84 import org.openecomp.sdc.tosca.services.DataModelUtil;
85 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
86 import org.openecomp.sdc.tosca.services.ToscaConstants;
87 import org.openecomp.sdc.tosca.services.ToscaUtil;
88 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
89 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedPropertyVal;
90 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
91 import org.openecomp.sdc.translator.datatypes.heattotosca.ReferenceType;
92 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
93 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
94 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
95 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
96 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
97 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailV2VirtualMachineInterfaceHelper;
98 import org.openecomp.sdc.translator.services.heattotosca.impl.functiontranslation.FunctionTranslator;
99 import org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation.ResourceTranslationBase;
100 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
103 * The type Heat to tosca util.
105 public class HeatToToscaUtil {
107 private static final Logger LOGGER = LoggerFactory.getLogger(HeatToToscaUtil.class);
108 private static final String FQ_NAME = "fq_name";
109 private static final String GET_PARAM = "get_param";
110 private static final String GET_ATTR = "get_attr";
111 private static final String GET_RESOURCE = "get_resource";
112 private static final String UNDERSCORE = "_";
113 private static final String WORDS_REGEX = "(\\w+)";
114 private static final String PORT_RESOURCE_ID_REGEX_SUFFIX = "(_\\d+)*";
115 private static final String PORT_RESOURCE_ID_REGEX_PREFIX = WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX;
116 private static final String PORT_INT_RESOURCE_ID_REGEX_PREFIX =
117 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + "int_" + WORDS_REGEX + UNDERSCORE;
118 private static final String SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX =
119 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + "subint_" + WORDS_REGEX + UNDERSCORE;
120 private static final String SUB_INTERFACE_REGEX =
121 WORDS_REGEX + PORT_RESOURCE_ID_REGEX_SUFFIX + "_subint_(\\w_+)*vmi" + PORT_RESOURCE_ID_REGEX_SUFFIX;
124 * Load and translate template data translator output.
126 * @param fileNameContentMap the file name content map
127 * @return the translator output
129 public static TranslatorOutput loadAndTranslateTemplateData(FileContentHandler fileNameContentMap) {
130 HeatToToscaTranslator heatToToscaTranslator = HeatToToscaTranslatorFactory.getInstance().createInterface();
132 try (InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME)) {
133 heatToToscaTranslator.addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
134 } catch (IOException e) {
135 throw new RuntimeException("Failed to read manifest", e);
138 fileNameContentMap.getFileList().stream().filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME)))
139 .forEach(fileName -> heatToToscaTranslator.addFile(fileName,
140 FileUtils.toByteArray(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, List<FileData> filesDataList,
176 FileData.Type... types) {
177 List<FileData> list = new ArrayList<>(filesDataList);
178 Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
179 if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
180 list.addAll(resourceFileData.get().getData());
182 return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
186 * Gets filtered list of file data by types.
188 * @param filesToSearch the files to search
189 * @param types the types
190 * @return the filtered list of file data by types
192 public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
193 FileData.Type... types) {
194 return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types)).collect(Collectors.toList());
198 * Gets file data from the list according to the input heat file name.
200 * @param heatFileName the heat file name
201 * @param fileDataList the file data list
202 * @return the file data
204 public static Optional<FileData> getFileData(String heatFileName, Collection<FileData> fileDataList) {
205 for (FileData file : fileDataList) {
206 if (file.getFile().equals(heatFileName)) {
207 return Optional.of(file);
210 return Optional.empty();
214 * Gets file data which is supported by the translator, from the context according the input heat
217 * @param heatFileName the heat file name
218 * @param context the translation context
219 * @return the file data
221 public static FileData getFileData(String heatFileName, TranslationContext context) {
222 List<FileData> fileDataList = context.getManifest().getContent().getData();
223 for (FileData fileData : fileDataList) {
224 if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType()) && fileData.getFile()
225 .equals(heatFileName)) {
232 static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList, Set<FileData.Type> typeFilter,
233 TranslationContext translationContext) {
234 FileDataCollection fileDataCollection = new FileDataCollection();
235 Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
236 Set<String> referenced = new HashSet<>();
238 for (FileData fileData : filteredFiles.values()) {
239 String fileName = fileData.getFile();
241 if (FileData.isHeatFile(fileData.getType())) {
242 if (fileData.getBase() != null && fileData.getBase()) {
243 fileDataCollection.addBaseFiles(fileData);
245 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil().yamlToObject(
246 translationContext.getFileContent(fileName), HeatOrchestrationTemplate.class);
247 if (MapUtils.isNotEmpty(heatOrchestrationTemplate.getResources())) {
248 applyFilterOnFileCollection(heatOrchestrationTemplate, translationContext, fileDataCollection,
249 filteredFiles, referenced);
253 fileDataCollection.addArtifactFiles(fileData);
254 filteredFiles.remove(fileData.getFile());
258 referenced.forEach(filteredFiles::remove);
259 if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
260 for (FileData fileData : fileDataCollection.getBaseFile()) {
261 filteredFiles.remove(fileData.getFile());
264 fileDataCollection.setAddOnFiles(filteredFiles.values());
265 return fileDataCollection;
268 private static void applyFilterOnFileCollection(HeatOrchestrationTemplate heatOrchestrationTemplate,
269 TranslationContext translationContext,
270 FileDataCollection fileDataCollection,
271 Map<String, FileData> filteredFiles,
272 Set<String> referenced) {
273 List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
275 for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
276 if (filenames.contains(resource.getType())) {
277 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced, resource.getType());
278 } else if (resource.getType().equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
279 handleResourceGrpNestedFile(resource, translationContext, fileDataCollection, filteredFiles, filenames,
285 private static void handleResourceGrpNestedFile(Resource resource, TranslationContext translationContext,
286 FileDataCollection fileDataCollection,
287 Map<String, FileData> filteredFiles, List<String> filenames,
288 Set<String> referenced) {
289 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
290 Object innerTypeDef = ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
291 if (innerTypeDef instanceof String) {
292 String internalResourceType = (String) innerTypeDef;
293 if (filenames.contains(internalResourceType)) {
294 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
295 internalResourceType);
300 private static void handleNestedFile(TranslationContext translationContext, FileDataCollection fileDataCollection,
301 Map<String, FileData> filteredFiles, Set<String> referenced,
302 String nestedFileName) {
303 referenced.add(nestedFileName);
304 fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
305 translationContext.getNestedHeatsFiles().add(nestedFileName);
308 private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
309 Set<FileData.Type> typesToGet) {
310 Map<String, FileData> filtered = new HashMap<>();
311 fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
312 .forEach(file -> filtered.put(file.getFile(), file));
316 private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
317 return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
321 * Extract attached resource id optional.
323 * @param translateTo the translate to
324 * @param propertyName the property name
325 * @return the optional
327 public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo, String propertyName) {
328 Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
329 if (propertyValue == null) {
330 return Optional.empty();
332 return extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
333 translateTo.getContext(), propertyValue);
337 * Extract attached resource id optional.
339 * @param heatFileName the heat file name
340 * @param heatOrchestrationTemplate the heat orchestration template
341 * @param context the context
342 * @param propertyValue the property value
343 * @return the optional
345 public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
346 HeatOrchestrationTemplate heatOrchestrationTemplate,
347 TranslationContext context,
348 Object propertyValue) {
353 if (Objects.isNull(propertyValue)) {
354 return Optional.empty();
357 ReferenceType referenceType = ReferenceType.OTHER;
358 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
359 Map<String, Object> propMap = (Map) propertyValue;
360 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
361 entity = entry.getValue();
362 String key = entry.getKey();
363 referenceType = getReferenceTypeFromAttachedResouce(key);
365 if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
368 FunctionTranslator functionTranslator = new FunctionTranslator(getFunctionTranslateTo(null, null,
369 heatFileName, heatOrchestrationTemplate, context), null, entry.getValue(), null);
370 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
371 .translateFunction(functionTranslator);
373 if (translatedId instanceof String
374 && !new FunctionTranslator().isResourceSupported((String) translatedId)) {
379 translatedId = propertyValue;
380 entity = propertyValue;
383 return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
386 private static ReferenceType getReferenceTypeFromAttachedResouce(String key) {
387 ReferenceType referenceType;
390 referenceType = ReferenceType.GET_RESOURCE;
393 referenceType = ReferenceType.GET_PARAM;
396 referenceType = ReferenceType.GET_ATTR;
399 referenceType = ReferenceType.OTHER;
403 return referenceType;
407 * Gets contrail attached heat resource id.
409 * @param attachedResource the attached resource
410 * @return the contrail attached heat resource id
412 public static Optional<String> getContrailAttachedHeatResourceId(AttachedResourceId attachedResource) {
413 if (attachedResource == null) {
414 return Optional.empty();
417 if (attachedResource.isGetResource()) {
418 return Optional.of((String) attachedResource.getEntityId());
421 if (attachedResource.isGetAttr()) {
422 return getResourceId(attachedResource.getEntityId());
424 return Optional.empty();
428 * Extract property optional.
430 * @param propertyValue the property value
431 * @return the optional
433 private static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
434 Object attachedPropertyVal;
435 if (Objects.isNull(propertyValue)) {
436 return Optional.empty();
439 ReferenceType referenceType = ReferenceType.OTHER;
440 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
441 Map<String, Object> propMap = (Map) propertyValue;
442 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
443 attachedPropertyVal = entry.getValue();
444 String key = entry.getKey();
447 referenceType = ReferenceType.GET_RESOURCE;
450 referenceType = ReferenceType.GET_PARAM;
453 referenceType = ReferenceType.GET_ATTR;
460 attachedPropertyVal = propertyValue;
462 return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
468 * @param nodeTemplate the node template
469 * @param propertyKey the property key
471 public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
472 Object value = nodeTemplate.getProperties().get(propertyKey);
473 if (value != null && !(value instanceof Map)) {
474 nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
481 * @param nodeTemplate the node template
482 * @param propertyListKey the property list key
484 public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
485 Object listValue = nodeTemplate.getProperties().get(propertyListKey);
486 if (listValue instanceof List) {
487 List booleanList = (List) listValue;
488 for (int i = 0; i < booleanList.size(); i++) {
489 Object value = booleanList.get(i);
490 if (value != null && !(value instanceof Map)) {
491 booleanList.set(i, HeatBoolean.eval(value));
499 * Is yml file type boolean.
501 * @param filename the filename
502 * @return the boolean
504 public static boolean isYmlFileType(String filename) {
505 String extension = FilenameUtils.getExtension(filename);
506 return "yaml".equalsIgnoreCase(extension) || "yml".equalsIgnoreCase(extension);
510 * Is nested resource boolean.
512 * @param resource the resource
513 * @return the boolean
515 public static boolean isNestedResource(Resource resource) {
516 String resourceType = resource.getType();
518 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
519 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
520 if (!(((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME) instanceof String)) {
521 //currently only resource group which is poinitng to nested heat file is supported
522 //dynamic type is currently not supported
525 String internalResourceType =
526 (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
527 if (isYamlFile(internalResourceType)) {
530 } else if (isYamlFile(resourceType)) {
537 * Checks if the current HEAT resource if of type sub interface.
539 * @param resource the resource
540 * @return true if the resource is of sub interface type and false otherwise
542 public static boolean isSubInterfaceResource(Resource resource, TranslationContext context) {
543 //Check if resource group is a nested resource
544 if (!isNestedResource(resource)) {
547 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
548 return nestedHeatFileName.filter(fileName -> isNestedVlanResource(fileName, context)).isPresent();
551 private static boolean isNestedVlanResource(String nestedHeatFileName, TranslationContext translationContext) {
552 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
553 translationContext.getFileContent(nestedHeatFileName), HeatOrchestrationTemplate.class);
554 return Objects.nonNull(nestedHeatOrchestrationTemplate.getResources()) && nestedHeatOrchestrationTemplate
555 .getResources().values()
557 new ContrailV2VirtualMachineInterfaceHelper()::isVlanSubInterfaceResource);
560 public static Optional<String> getSubInterfaceParentPortNodeTemplateId(TranslateTo subInterfaceTo) {
561 String subInterfaceResourceType = getSubInterfaceResourceType(subInterfaceTo.getResource());
562 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
563 subInterfaceTo.getContext().getFileContent(subInterfaceResourceType), HeatOrchestrationTemplate.class);
564 if (Objects.isNull(nestedHeatOrchestrationTemplate.getResources())) {
565 return Optional.empty();
567 for (Map.Entry<String, Resource> resourceEntry : nestedHeatOrchestrationTemplate.getResources().entrySet()) {
568 Resource resource = resourceEntry.getValue();
569 if (isVmiRefsPropertyExists(resource)) {
570 Object toscaPropertyValue = TranslatorHeatToToscaPropertyConverter
571 .getToscaPropertyValue(subInterfaceTo.getServiceTemplate(),
572 resourceEntry.getKey(),
573 HeatConstants.VMI_REFS_PROPERTY_NAME,
574 resource.getProperties()
575 .get(HeatConstants.VMI_REFS_PROPERTY_NAME),
576 resource.getType(), subInterfaceResourceType,
577 nestedHeatOrchestrationTemplate, null,
578 subInterfaceTo.getContext());
579 return getParentNodeTemplateIdFromPropertyValue(toscaPropertyValue, subInterfaceTo);
582 return Optional.empty();
585 private static boolean isVmiRefsPropertyExists(Resource resource) {
586 return HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource()
587 .equals(resource.getType())
588 && MapUtils.isNotEmpty(resource.getProperties()) && resource.getProperties().containsKey(
589 HeatConstants.VMI_REFS_PROPERTY_NAME);
592 public static String getSubInterfaceResourceType(Resource resource) {
593 if (!HeatToToscaUtil.isYamlFile(resource.getType())) {
594 return ((Map) resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
595 .get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME).toString();
597 return resource.getType();
600 private static Optional<String> getParentNodeTemplateIdFromPropertyValue(Object toscaPropertyValue,
601 TranslateTo subInterfaceTo) {
602 if (toscaPropertyValue instanceof List && ((List) toscaPropertyValue).get(0) instanceof Map) {
603 Resource subInterfaceResource = subInterfaceTo.getResource();
604 Map<String, String> toscaPropertyValueMap = (Map) ((List) toscaPropertyValue).get(0);
605 String parentPortPropertyInput = toscaPropertyValueMap.get(ToscaFunctions.GET_INPUT.getDisplayName());
606 Map<String, Object> resourceDefPropertiesMap;
607 if (!isYamlFile(subInterfaceResource.getType())) {
608 resourceDefPropertiesMap =
609 (Map) ((Map) subInterfaceResource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME))
610 .get(HeatConstants.RESOURCE_DEF_PROPERTIES);
612 resourceDefPropertiesMap = subInterfaceResource.getProperties();
614 Object parentPortObj = resourceDefPropertiesMap.get(parentPortPropertyInput);
615 if (parentPortObj instanceof Map) {
616 Map<String, String> parentPortPropertyValue = (Map) parentPortObj;
617 if (parentPortPropertyValue.keySet().contains(ResourceReferenceFunctions.GET_RESOURCE.getFunction())) {
618 return ResourceTranslationBase.getResourceTranslatedId(subInterfaceTo.getHeatFileName(),
619 subInterfaceTo.getHeatOrchestrationTemplate(),
620 parentPortPropertyValue.get(ResourceReferenceFunctions.GET_RESOURCE.getFunction()),
621 subInterfaceTo.getContext());
625 return Optional.empty();
629 * Checks if the nested resource represents a VFC or a complex VFC (Heat file should contain at
630 * least one or more compute nodes).
632 * @param resource the resource
633 * @param context the context
634 * @return true if the resource represents a VFC and false otherwise.
636 public static boolean isNestedVfcResource(Resource resource, TranslationContext context) {
637 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
638 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
639 context.getFileContent(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
640 if (Objects.nonNull(nestedHeatOrchestrationTemplate.getResources())) {
641 for (String innerResourceId : nestedHeatOrchestrationTemplate.getResources().keySet()) {
642 if (ConsolidationDataUtil.isComputeResource(nestedHeatOrchestrationTemplate, innerResourceId)) {
651 * Get nested heat file name in case of nested resource.
653 * @param resource the resource
654 * @return the nested heat file name
656 private static Optional<String> getNestedHeatFileName(Resource resource) {
657 if (!isNestedResource(resource)) {
658 return Optional.empty();
661 String resourceType = resource.getType();
663 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
664 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
665 String internalResourceType =
666 (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
667 return Optional.of(internalResourceType);
669 return Optional.of(resourceType);
675 * @param resource the resource
676 * @return the nested file
678 public static Optional<String> getNestedFile(Resource resource) {
679 if (!isNestedResource(resource)) {
680 return Optional.empty();
682 String resourceType = resource.getType();
683 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
684 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
685 String internalResourceType =
686 (String) ((Map) resourceDef).get(HeatConstants.RESOURCE_DEF_TYPE_PROPERTY_NAME);
687 return Optional.of(internalResourceType);
689 return Optional.of(resourceType);
693 public static boolean isYamlFile(String fileName) {
694 return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
700 * @param heatOrchestrationTemplate the heat orchestration template
701 * @param resourceId the resource id
702 * @param heatFileName the heat file name
703 * @return the resource
705 public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate, String resourceId,
706 String heatFileName) {
707 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
708 if (resource == null) {
709 throw new CoreException(new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
718 * @param resourceId the resource id
719 * @param heatOrchestrationTemplate heat orchestration template
720 * @param heatFileName heat file name
721 * @return resource type
723 public static String getResourceType(String resourceId, HeatOrchestrationTemplate heatOrchestrationTemplate,
724 String heatFileName) {
725 return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName).getType();
729 * Is heat file nested boolean.
731 * @param translateTo the translate to
732 * @param heatFileName the heat file name
733 * @return the boolean
735 public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
736 return isHeatFileNested(translateTo.getContext(), heatFileName);
739 public static boolean isHeatFileNested(TranslationContext context, String heatFileName) {
740 return context.getNestedHeatsFiles().contains(heatFileName);
744 * Extract contrail get resource attached heat resource id optional.
746 * @param propertyValue the property value
747 * @return the optional
749 public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(Object propertyValue) {
750 if (propertyValue instanceof Map) {
751 if (((Map) propertyValue).containsKey(GET_ATTR)) {
752 return getResourceId(((Map) propertyValue).get(GET_ATTR));
753 } else if (((Map) propertyValue).containsKey(GET_RESOURCE)) {
754 return getHeatResourceIdFromResource((Map) propertyValue);
756 Collection valCollection = ((Map) propertyValue).values();
757 return evaluateHeatResourceId(valCollection);
759 } else if (propertyValue instanceof List) {
760 return evaluateHeatResourceId((List) propertyValue);
762 return Optional.empty();
765 private static Optional<String> getResourceId(Object data) {
766 if (data instanceof List && CollectionUtils.size(data) > 1 && FQ_NAME.equals(((List) data).get(1))
767 && ((List) data).get(0) instanceof String) {
768 return Optional.of((String) ((List) data).get(0));
770 LOGGER.warn("invalid format of 'get_attr' function - " + data.toString());
771 return Optional.empty();
775 private static Optional<String> getHeatResourceIdFromResource(Map propertyValue) {
776 Object value = propertyValue.get(GET_RESOURCE);
777 if (value instanceof String) {
778 return Optional.of((String) value);
780 LOGGER.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
781 return Optional.empty();
785 private static Optional<String> evaluateHeatResourceId(Collection propertyValue) {
786 for (Object prop : propertyValue) {
787 Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
788 if (ret.isPresent()) {
792 return Optional.empty();
796 * Gets tosca service model.
798 * @param context translation context
799 * @return the tosca service model
801 public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
802 Map<String, String> metadata = new HashMap<>();
803 metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
804 return getToscaServiceModel(context, metadata);
808 * Gets tosca service model.
810 * @param context translation context
811 * @param entryDefinitionMetadata template name of the entry definition servie template
812 * @return the tosca service model
814 private static ToscaServiceModel getToscaServiceModel(TranslationContext context,
815 Map<String, String> entryDefinitionMetadata) {
816 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(context.getGlobalServiceTemplates());
817 Collection<ServiceTemplate> tmpServiceTemplates = context.getTranslatedServiceTemplates().values();
818 for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
819 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
821 return new ToscaServiceModel(null, serviceTemplates,
822 ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
826 * Gets service template from context.
828 * @param serviceTemplateFileName the service template file name
829 * @param context the context
830 * @return the service template from context
832 public static Optional<ServiceTemplate> getServiceTemplateFromContext(String serviceTemplateFileName,
833 TranslationContext context) {
834 for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
835 if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
836 return Optional.of(serviceTemplate);
839 return Optional.empty();
843 * Adding link requerment from port node template to network node template.
845 * @param portNodeTemplate port node template
846 * @param networkTranslatedId network node template id
848 public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
849 String networkTranslatedId) {
850 RequirementAssignment requirement = new RequirementAssignment();
851 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
852 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
853 requirement.setNode(networkTranslatedId);
854 DataModelUtil.addRequirementAssignment(portNodeTemplate, ToscaConstants.LINK_REQUIREMENT_ID, requirement);
859 * Adding binding requerment from sub interface node template to interface (port) node template.
861 * @param subInterfaceNodeTemplate sub interface template
862 * @param interfaceTranslatedId interface node template id
864 public static void addBindingReqFromSubInterfaceToInterface(NodeTemplate subInterfaceNodeTemplate,
865 String interfaceTranslatedId) {
866 RequirementAssignment requirement = new RequirementAssignment();
867 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
868 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
869 requirement.setNode(interfaceTranslatedId);
871 .addRequirementAssignment(subInterfaceNodeTemplate, ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
875 * Get property Parameter Name Value.
877 * @param property property
878 * @return Parameter name in case the property include "get_param" function
880 public static Optional<String> getPropertyParameterNameValue(Object property) {
881 if (Objects.isNull(property)) {
882 return Optional.empty();
884 Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
885 if (extractedProperty.isPresent()) {
886 return getParameterName(extractedProperty.get());
888 return Optional.empty();
891 private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
892 if (!extractedProperty.isGetParam()) {
893 return Optional.empty();
895 Object getParamFuncValue = extractedProperty.getPropertyValue();
896 if (getParamFuncValue instanceof String) {
897 return Optional.of((String) getParamFuncValue);
899 return Optional.of((String) ((List) getParamFuncValue).get(0));
903 public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
904 String heatPropertyName) {
905 return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
909 * Gets tosca property name.
911 * @param translateTo the translate to
912 * @param heatPropertyName the heat property name
913 * @return the tosca property name
915 public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
916 return translateTo.getContext()
917 .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
921 * Gets tosca attribute name.
923 * @param context the context
924 * @param heatResourceType the heat resource type
925 * @param heatAttrName the heat attr name
926 * @return the tosca attribute name
928 public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
929 String heatAttrName) {
930 return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
934 * Gets tosca attribute name.
936 * @param translateTo the translate to
937 * @param heatAttrName the heat attr name
938 * @return the tosca attribute name
940 public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
941 return translateTo.getContext()
942 .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
946 * Create init substitution service template service template.
948 * @param templateName the template name
949 * @return the service template
951 public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
952 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
953 Map<String, String> templateMetadata = new HashMap<>();
954 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
955 nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
956 nestedSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
957 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
958 List<Map<String, Import>> globalTypesImportList = GlobalTypesGenerator.getGlobalTypesImportList();
959 globalTypesImportList
960 .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
961 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
962 return nestedSubstitutionServiceTemplate;
966 * Create init global substitution service template service template.
968 * @return the service template
970 private static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
971 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
972 Map<String, String> templateMetadata = new HashMap<>();
974 .put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
975 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
976 globalSubstitutionServiceTemplate.setImports(GlobalTypesGenerator.getGlobalTypesImportList());
977 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
978 return globalSubstitutionServiceTemplate;
982 * Create substitution node type node type.
984 * @param substitutionServiceTemplate the substitution service template
985 * @return the node type
987 public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
988 NodeType substitutionNodeType = new NodeType();
989 substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
990 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
991 substitutionNodeType.setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
992 substitutionNodeType.setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
993 return substitutionNodeType;
996 private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(ServiceTemplate substitutionServiceTemplate) {
997 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
998 Map<String, ParameterDefinition> properties = substitutionServiceTemplate.getTopology_template().getInputs();
999 if (properties == null) {
1003 PropertyDefinition propertyDefinition;
1004 String toscaPropertyName;
1005 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
1006 toscaPropertyName = entry.getKey();
1007 propertyDefinition = new PropertyDefinition();
1008 ParameterDefinition parameterDefinition =
1009 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
1010 propertyDefinition.setType(parameterDefinition.getType());
1011 propertyDefinition.setDescription(parameterDefinition.getDescription());
1012 propertyDefinition.setRequired(parameterDefinition.getRequired());
1013 propertyDefinition.set_default(parameterDefinition.get_default());
1014 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
1015 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1016 propertyDefinition.setStatus(parameterDefinition.getStatus());
1017 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1019 return substitutionNodeTypeProperties;
1022 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(ServiceTemplate substitutionServiceTemplate) {
1023 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1024 Map<String, ParameterDefinition> attributes = substitutionServiceTemplate.getTopology_template().getOutputs();
1025 if (attributes == null) {
1028 AttributeDefinition attributeDefinition;
1029 String toscaAttributeName;
1031 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1032 attributeDefinition = new AttributeDefinition();
1033 toscaAttributeName = entry.getKey();
1034 ParameterDefinition parameterDefinition =
1035 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1036 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1037 attributeDefinition.setType(parameterDefinition.getType());
1039 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1041 attributeDefinition.setDescription(parameterDefinition.getDescription());
1042 attributeDefinition.set_default(parameterDefinition.get_default());
1043 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1044 attributeDefinition.setStatus(parameterDefinition.getStatus());
1045 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1047 return substitutionNodeTypeAttributes;
1052 * Create and add substitution mapping to the nested substitution service template, and update
1053 * the subtitution node type accordingly with the exposed requerments and capabilities
1055 * @param context the translation context
1056 * @param substitutionNodeTypeKey the substitution node type key
1057 * @param nestedSubstitutionServiceTemplate the nested substitution service template
1058 * @param substitutionNodeType the substitution node type
1060 public static void handleSubstitutionMapping(TranslationContext context, String substitutionNodeTypeKey,
1061 ServiceTemplate nestedSubstitutionServiceTemplate,
1062 NodeType substitutionNodeType) {
1063 Map<String, Map<String, List<String>>> substitutionMapping =
1064 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType, nestedSubstitutionServiceTemplate,
1066 //add substitution mapping after capability and requirement expose calculation
1067 nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(DataModelUtil
1068 .createSubstitutionTemplateSubMapping(
1069 substitutionNodeTypeKey,
1070 substitutionNodeType,
1071 substitutionMapping));
1075 * Gets node type with flat hierarchy.
1077 * @param nodeTypeId the node type id
1078 * @param serviceTemplate the service template
1079 * @param context the context
1080 * @return the node type with flat hierarchy
1082 public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId, ServiceTemplate serviceTemplate,
1083 TranslationContext context) {
1084 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1085 ToscaServiceModel toscaServiceModel =
1086 HeatToToscaUtil.getToscaServiceModel(context, serviceTemplate.getMetadata());
1087 return (NodeType) toscaAnalyzerService.getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate,
1088 toscaServiceModel).getFlatEntity();
1093 * Create abstract substitution node template.
1095 * @param translateTo the translate to
1096 * @param templateName the template name
1097 * @param substitutionNodeTypeKey the substitution node type key
1098 * @return the abstract substitute node template
1100 public static NodeTemplate createAbstractSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1101 String substitutionNodeTypeKey) {
1102 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1103 List<String> directiveList = new ArrayList<>();
1104 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1105 substitutionNodeTemplate.setDirectives(directiveList);
1106 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1107 substitutionNodeTemplate.setProperties(
1108 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate, templateName));
1109 return substitutionNodeTemplate;
1114 * Checks if the source and target resource is a valid candidate for adding tosca dependency
1117 * @param sourceResource the source resource
1118 * @param targetResource the target resource
1119 * @param dependencyEntity the dependency entity
1120 * @return true if the candidate resources are a valid combination for the dependency relationship
1121 * and false otherwise
1123 public static boolean isValidDependsOnCandidate(Resource sourceResource, Resource targetResource,
1124 ConsolidationEntityType dependencyEntity,
1125 TranslationContext context) {
1126 dependencyEntity.setEntityType(sourceResource, targetResource, context);
1127 ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1128 ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1130 return ConsolidationTypesConnectivity.isDependsOnRelationshipValid(sourceEntityType, targetEntityType);
1133 private static Map<String, Object> managerSubstitutionNodeTemplateProperties(TranslateTo translateTo,
1135 String templateName) {
1136 Map<String, Object> substitutionProperties = new HashMap<>();
1137 Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1138 if (Objects.nonNull(heatProperties)) {
1139 for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1140 Object property = TranslatorHeatToToscaPropertyConverter
1141 .getToscaPropertyValue(translateTo.getServiceTemplate(),
1142 translateTo.getTranslatedId(), entry.getKey(), entry.getValue(), null,
1143 translateTo.getHeatFileName(),
1144 translateTo.getHeatOrchestrationTemplate(), template,
1145 translateTo.getContext());
1146 substitutionProperties.put(entry.getKey(), property);
1149 return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1152 private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1153 Map<String, Object> substitutionProperties) {
1154 Map<String, Object> innerProps = new HashMap<>();
1155 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1156 ToscaUtil.getServiceTemplateFileName(templateName));
1157 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1158 return substitutionProperties;
1161 private static Map<String, Map<String, List<String>>> getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1162 ServiceTemplate substitutionServiceTemplate,
1163 TranslationContext context) {
1164 Map<String, NodeTemplate> nodeTemplates =
1165 substitutionServiceTemplate.getTopology_template().getNode_templates();
1166 String nodeTemplateId;
1167 NodeTemplate nodeTemplate;
1169 Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1170 if (nodeTemplates == null) {
1171 return substitutionMapping;
1174 Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1175 Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1176 substitutionMapping.put("capability", capabilitySubstitutionMapping);
1177 substitutionMapping.put("requirement", requirementSubstitutionMapping);
1178 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1179 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1180 List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1181 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition = new HashMap<>();
1182 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1183 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1184 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1186 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1187 nodeTemplateId = entry.getKey();
1188 nodeTemplate = entry.getValue();
1189 nodeType = nodeTemplate.getType();
1192 nodeTypeRequirementsDefinition = getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1193 requirementSubstitutionMapping, context);
1194 nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1195 fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1196 //set substitution node type requirements
1197 exposedRequirementsDefinition = toscaAnalyzerService
1198 .calculateExposedRequirements(nodeTypeRequirementsDefinition,
1199 nodeTemplateRequirementsAssignment);
1200 DataModelUtil.addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1204 addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping, nodeType,
1205 nodeTemplateId, substitutionServiceTemplate, context);
1208 exposedCapabilitiesDefinition = toscaAnalyzerService
1209 .calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1210 fullFilledRequirementsDefinition);
1211 DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1212 return substitutionMapping;
1215 private static void addNodeTypeCapabilitiesToSubMapping(Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1216 Map<String, List<String>> capabilitySubstitutionMapping,
1217 String type, String templateName,
1218 ServiceTemplate serviceTemplate,
1219 TranslationContext context) {
1220 NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1222 if (flatNodeType.getCapabilities() != null) {
1223 flatNodeType.getCapabilities().entrySet().stream().forEach(
1224 capabilityNodeEntry -> addCapabilityToSubMapping(templateName, capabilityNodeEntry,
1225 nodeTypeCapabilitiesDefinition, capabilitySubstitutionMapping));
1229 private static void addCapabilityToSubMapping(String templateName,
1230 Map.Entry<String, CapabilityDefinition> capabilityNodeEntry,
1231 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1232 Map<String, List<String>> capabilitySubstitutionMapping) {
1233 String capabilityKey;
1234 List<String> capabilityMapping;
1235 capabilityKey = capabilityNodeEntry.getKey() + UNDERSCORE + templateName;
1236 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1237 capabilityMapping = new ArrayList<>();
1238 capabilityMapping.add(templateName);
1239 capabilityMapping.add(capabilityNodeEntry.getKey());
1240 capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1243 private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(String type, String templateName,
1244 ServiceTemplate serviceTemplate,
1245 Map<String, List<String>> requirementSubstitutionMapping,
1246 TranslationContext context) {
1247 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1248 NodeType flatNodeType = getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1249 List<String> requirementMapping;
1251 if (flatNodeType.getRequirements() == null) {
1252 return requirementList;
1255 for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1256 for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap.entrySet()) {
1257 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1258 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil.yamlToObject(
1259 toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1260 RequirementDefinition.class);
1261 if (Objects.isNull(requirementNodeEntryValue.getOccurrences())) {
1262 requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1264 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1265 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1266 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1267 requirementMapping = new ArrayList<>();
1268 requirementMapping.add(templateName);
1269 requirementMapping.add(requirementNodeEntry.getKey());
1270 requirementSubstitutionMapping
1271 .put(requirementNodeEntry.getKey() + UNDERSCORE + templateName, requirementMapping);
1272 if (Objects.isNull(requirementNodeEntryValue.getNode())) {
1273 requirementNodeEntryValue.setOccurrences(new Object[] {1, 1});
1277 return requirementList;
1281 * Fetch global substitution service template service template.
1283 * @param serviceTemplate the service template
1284 * @param context the context
1285 * @return the service template
1287 public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(ServiceTemplate serviceTemplate,
1288 TranslationContext context) {
1289 ServiceTemplate globalSubstitutionServiceTemplate =
1290 context.getTranslatedServiceTemplates().get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1291 if (globalSubstitutionServiceTemplate == null) {
1292 globalSubstitutionServiceTemplate = HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1293 context.getTranslatedServiceTemplates()
1294 .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME, globalSubstitutionServiceTemplate);
1296 boolean isImportAddedToServiceTemplate = DataModelUtil
1297 .isImportAddedToServiceTemplate(serviceTemplate.getImports(),
1298 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1299 if (!isImportAddedToServiceTemplate) {
1300 serviceTemplate.getImports()
1301 .addAll(HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1303 return globalSubstitutionServiceTemplate;
1306 public static List<Map<String, Import>> createImportList(String templateName) {
1307 List<Map<String, Import>> imports = new ArrayList<>();
1308 Map<String, Import> importsMap = new HashMap<>();
1309 importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1310 imports.add(importsMap);
1315 * Create service template import import.
1317 * @param serviceTemplate the service template
1318 * @return the import
1320 public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1321 Import serviceTemplateImport = new Import();
1322 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1323 return serviceTemplateImport;
1327 * Create service template import import.
1329 * @param metadataTemplateName the service template name
1330 * @return the import
1332 private static Import createServiceTemplateImport(String metadataTemplateName) {
1333 Import serviceTemplateImport = new Import();
1334 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1335 return serviceTemplateImport;
1338 public static ToscaServiceModel createToscaServiceModel(ServiceTemplate entryDefinitionServiceTemplate,
1339 TranslationContext translationContext) {
1340 return new ToscaServiceModel(getCsarArtifactFiles(translationContext), getServiceTemplates(translationContext),
1341 ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1344 private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1345 FileContentHandler artifactFiles = new FileContentHandler();
1346 artifactFiles.setFiles(translationContext.getFiles());
1347 artifactFiles.setFiles(translationContext.getExternalArtifacts());
1349 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1350 heatTreeManager.createTree();
1351 ValidationStructureList validationStructureList = new ValidationStructureList(heatTreeManager.getTree());
1352 byte[] validationStructureFile =
1353 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1354 artifactFiles.addFile("HEAT.meta", validationStructureFile);
1355 return artifactFiles;
1359 private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext translationContext) {
1360 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1361 serviceTemplates.addAll(GlobalTypesGenerator.getGlobalTypesServiceTemplate(OnboardingTypesEnum.ZIP).values());
1362 serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1363 Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1365 for (ServiceTemplate template : serviceTemplates) {
1366 serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1368 return serviceTemplatesMap;
1371 public static String getNestedResourceTypePrefix(TranslateTo translateTo) {
1372 if (isSubInterfaceResource(translateTo.getResource(), translateTo.getContext()) && isSubInterfaceBoundToPort(
1374 return ToscaNodeType.VLAN_SUB_INTERFACE_RESOURCE_TYPE_PREFIX;
1376 return ToscaNodeType.NESTED_HEAT_RESOURCE_TYPE_PREFIX;
1379 private static boolean isSubInterfaceBoundToPort(TranslateTo translateTo) {
1380 return HeatToToscaUtil.getSubInterfaceParentPortNodeTemplateId(translateTo).isPresent();
1383 //Method evaluate the network role from sub interface node template id, designed considering
1384 // only single sub interface present in nested file else it will return null
1385 public static Optional<String> getNetworkRoleFromSubInterfaceId(Resource resource,
1386 TranslationContext translationContext) {
1387 Optional<String> networkRole = Optional.empty();
1388 Optional<String> nestedHeatFileName = HeatToToscaUtil.getNestedHeatFileName(resource);
1390 if (!nestedHeatFileName.isPresent()) {
1394 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil().yamlToObject(
1395 translationContext.getFileContent(nestedHeatFileName.get()), HeatOrchestrationTemplate.class);
1397 if (MapUtils.isNotEmpty(nestedHeatOrchestrationTemplate.getResources())) {
1398 ContrailV2VirtualMachineInterfaceHelper contrailV2VirtualMachineInterfaceHelper =
1399 new ContrailV2VirtualMachineInterfaceHelper();
1400 Optional<Map.Entry<String, Resource>> vlanSubInterfaceResource =
1401 nestedHeatOrchestrationTemplate.getResources().entrySet().stream()
1402 .filter(resourceEntry -> contrailV2VirtualMachineInterfaceHelper
1403 .isVlanSubInterfaceResource(
1404 resourceEntry.getValue()))
1406 if (vlanSubInterfaceResource.isPresent()) {
1407 Map.Entry<String, Resource> vlanSubInterfaceResourceEntry = vlanSubInterfaceResource.get();
1408 networkRole = extractNetworkRoleFromSubInterfaceId(vlanSubInterfaceResourceEntry.getKey(),
1409 vlanSubInterfaceResourceEntry.getValue().getType());
1415 public static Optional<String> evaluateNetworkRoleFromResourceId(String resourceId, String resourceType) {
1416 Optional<PortType> portType = getPortType(resourceType);
1417 if (portType.isPresent()) {
1418 String portResourceIdRegex =
1419 PORT_RESOURCE_ID_REGEX_PREFIX + UNDERSCORE + WORDS_REGEX + UNDERSCORE + portType.get()
1421 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1422 String portIntResourceIdRegex = PORT_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
1423 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1425 String portNetworkRole = getNetworkRole(resourceId, portResourceIdRegex);
1426 String portIntNetworkRole = getNetworkRole(resourceId, portIntResourceIdRegex);
1428 return Optional.ofNullable(Objects.nonNull(portNetworkRole) ? portNetworkRole : portIntNetworkRole);
1430 return Optional.empty();
1433 private static Optional<PortType> getPortType(String resourceType) {
1435 .equals(HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())) {
1436 return Optional.of(PortType.VMI);
1437 } else if (resourceType.equals(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource())) {
1438 return Optional.of(PortType.PORT);
1440 return Optional.empty();
1443 public static Optional<String> extractNetworkRoleFromSubInterfaceId(String resourceId, String resourceType) {
1444 Optional<PortType> portType = getPortType(resourceType);
1445 if (portType.isPresent()) {
1446 String subInterfaceResourceIdRegex =
1447 SUB_INTERFACE_INT_RESOURCE_ID_REGEX_PREFIX + portType.get().getPortTypeName()
1448 + PORT_RESOURCE_ID_REGEX_SUFFIX;
1450 return Optional.ofNullable(getNetworkRole(resourceId, subInterfaceResourceIdRegex));
1452 return Optional.empty();
1455 private enum PortType {
1456 PORT("port"), VMI("vmi");
1458 private String portTypeName;
1460 PortType(String portTypeName) {
1461 this.portTypeName = portTypeName;
1464 public String getPortTypeName() {
1465 return portTypeName;
1469 private static String getNetworkRole(String portResourceId, String portIdRegex) {
1470 Pattern pattern = Pattern.compile(portIdRegex);
1471 Matcher matcher = pattern.matcher(portResourceId);
1472 if (matcher.matches()) {
1473 String networkRole = matcher.group(3);
1474 //Assuming network role will not contain ONLY digits
1475 if (!networkRole.matches("\\d+")) {
1476 return matcher.group(3);