2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca;
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.apache.commons.collections4.MapUtils;
25 import org.openecomp.core.translator.api.HeatToToscaTranslator;
26 import org.openecomp.core.translator.datatypes.TranslatorOutput;
27 import org.openecomp.core.translator.factory.HeatToToscaTranslatorFactory;
28 import org.openecomp.core.utilities.CommonMethods;
29 import org.openecomp.core.utilities.file.FileContentHandler;
30 import org.openecomp.core.utilities.file.FileUtils;
31 import org.openecomp.core.utilities.yaml.YamlUtil;
32 import org.openecomp.core.validation.util.MessageContainerUtil;
33 import org.openecomp.sdc.common.errors.CoreException;
34 import org.openecomp.sdc.common.utils.SdcCommon;
35 import org.openecomp.sdc.datatypes.error.ErrorLevel;
36 import org.openecomp.sdc.datatypes.error.ErrorMessage;
37 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
38 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
39 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
40 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
41 import org.openecomp.sdc.heat.datatypes.model.Resource;
42 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
43 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
44 import org.openecomp.sdc.heat.services.HeatConstants;
45 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
46 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
47 import org.openecomp.sdc.logging.api.Logger;
48 import org.openecomp.sdc.logging.api.LoggerFactory;
49 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
50 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
51 import org.openecomp.sdc.logging.types.LoggerConstants;
52 import org.openecomp.sdc.logging.types.LoggerErrorCode;
53 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
54 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
55 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
56 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
57 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
58 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
59 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
60 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
61 import org.openecomp.sdc.tosca.datatypes.model.CapabilityDefinition;
62 import org.openecomp.sdc.tosca.datatypes.model.Import;
63 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
64 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
65 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
66 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
67 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
68 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
69 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
70 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
71 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
72 import org.openecomp.sdc.tosca.datatypes.model.Template;
73 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
74 import org.openecomp.sdc.tosca.services.DataModelUtil;
75 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
76 import org.openecomp.sdc.tosca.services.ToscaConstants;
77 import org.openecomp.sdc.tosca.services.ToscaUtil;
78 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
79 import org.openecomp.sdc.tosca.services.yamlutil.ToscaExtensionYamlUtil;
80 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedPropertyVal;
81 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
82 import org.openecomp.sdc.translator.datatypes.heattotosca.ReferenceType;
83 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
84 import org.openecomp.sdc.translator.datatypes.heattotosca.to.FileDataCollection;
85 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
86 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
87 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
88 import org.openecomp.sdc.translator.services.heattotosca.helper.FunctionTranslationHelper;
89 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
91 import java.io.InputStream;
92 import java.util.ArrayList;
93 import java.util.Collection;
94 import java.util.HashMap;
95 import java.util.HashSet;
96 import java.util.List;
98 import java.util.Objects;
99 import java.util.Optional;
100 import java.util.Set;
101 import java.util.stream.Collectors;
104 * The type Heat to tosca util.
106 public class HeatToToscaUtil {
108 protected static Logger logger = (Logger) LoggerFactory.getLogger(HeatToToscaUtil.class);
109 protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
113 * Load and translate template data translator output.
115 * @param fileNameContentMap the file name content map
116 * @return the translator output
118 public static TranslatorOutput loadAndTranslateTemplateData(
119 FileContentHandler fileNameContentMap) {
120 mdcDataDebugMessage.debugEntryMessage(null, null);
121 HeatToToscaTranslator heatToToscaTranslator =
122 HeatToToscaTranslatorFactory.getInstance().createInterface();
123 InputStream fileContent = fileNameContentMap.getFileContent(SdcCommon.MANIFEST_NAME);
125 heatToToscaTranslator.addManifest(SdcCommon.MANIFEST_NAME, FileUtils.toByteArray(fileContent));
127 fileNameContentMap.getFileList().stream()
128 .filter(fileName -> !(fileName.equals(SdcCommon.MANIFEST_NAME))).forEach(
129 fileName -> heatToToscaTranslator
130 .addFile(fileName, FileUtils.toByteArray
131 (fileNameContentMap.getFileContent(fileName))));
133 Map<String, List<ErrorMessage>> errors = heatToToscaTranslator.validate();
134 if (MapUtils.isNotEmpty(MessageContainerUtil.getMessageByLevel(ErrorLevel.ERROR, errors))) {
135 TranslatorOutput translatorOutput = new TranslatorOutput();
136 translatorOutput.setErrorMessages(errors);
137 return translatorOutput;
140 InputStream structureFile = getHeatStructureTreeFile(fileNameContentMap);
141 heatToToscaTranslator.addExternalArtifacts(SdcCommon.HEAT_META, structureFile);
143 mdcDataDebugMessage.debugExitMessage(null, null);
144 return heatToToscaTranslator.translate();
148 private static InputStream getHeatStructureTreeFile(FileContentHandler fileNameContentMap) {
149 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileNameContentMap);
150 heatTreeManager.createTree();
151 HeatStructureTree tree = heatTreeManager.getTree();
152 ValidationStructureList validationStructureList = new ValidationStructureList(tree);
153 return FileUtils.convertToInputStream(validationStructureList, FileUtils.FileExtension.JSON);
157 * Build list of files to search optional.
159 * @param heatFileName the heat file name
160 * @param filesDataList the files data list
161 * @param types the types
162 * @return the optional
164 public static Optional<List<FileData>> buildListOfFilesToSearch(String heatFileName,
165 List<FileData> filesDataList,
166 FileData.Type... types) {
167 List<FileData> list = new ArrayList<>(filesDataList);
168 Optional<FileData> resourceFileData = HeatToToscaUtil.getFileData(heatFileName, filesDataList);
169 if (resourceFileData.isPresent() && Objects.nonNull(resourceFileData.get().getData())) {
170 list.addAll(resourceFileData.get().getData());
172 return Optional.ofNullable(HeatToToscaUtil.getFilteredListOfFileDataByTypes(list, types));
176 * Gets filtered list of file data by types.
178 * @param filesToSearch the files to search
179 * @param types the types
180 * @return the filtered list of file data by types
182 public static List<FileData> getFilteredListOfFileDataByTypes(List<FileData> filesToSearch,
183 FileData.Type... types) {
184 return filesToSearch.stream().filter(FileData.buildFileDataPredicateByType(types))
185 .collect(Collectors.toList());
189 * Gets file data from the list according to the input heat file name.
191 * @param heatFileName the heat file name
192 * @param fileDataList the file data list
193 * @return the file data
195 public static Optional<FileData> getFileData(String heatFileName,
196 Collection<FileData> fileDataList) {
197 for (FileData file : fileDataList) {
198 if (file.getFile().equals(heatFileName)) {
199 return Optional.of(file);
202 return Optional.empty();
206 * Gets file data which is supported by the translator, from the context according the input heat
209 * @param heatFileName the heat file name
210 * @param context the translation context
211 * @return the file data
213 public static FileData getFileData(String heatFileName, TranslationContext context) {
215 List<FileData> fileDataList = context.getManifest().getContent().getData();
216 for (FileData fileData : fileDataList) {
217 if (TranslationService.getTypesToProcessByTranslator().contains(fileData.getType())
218 && fileData.getFile().equals(heatFileName)) {
225 static FileDataCollection getFileCollectionsByFilter(List<FileData> fileDataList,
226 Set<FileData.Type> typeFilter,
227 TranslationContext translationContext) {
228 FileDataCollection fileDataCollection = new FileDataCollection();
229 Map<String, FileData> filteredFiles = filterFileDataListByType(fileDataList, typeFilter);
230 Set<String> referenced = new HashSet<>();
231 List<String> filenames = extractFilenamesFromFileDataList(filteredFiles.values());
233 for (FileData fileData : filteredFiles.values()) {
234 String fileName = fileData.getFile();
236 if (FileData.isHeatFile(fileData.getType())) {
237 if (fileData.getBase() != null && fileData.getBase().equals(true)) {
238 fileDataCollection.addBaseFiles(fileData);
240 HeatOrchestrationTemplate heatOrchestrationTemplate = new YamlUtil()
241 .yamlToObject(translationContext.getFileContent(fileName),
242 HeatOrchestrationTemplate.class);
243 if (!MapUtils.isEmpty(heatOrchestrationTemplate.getResources())) {
244 for (Resource resource : heatOrchestrationTemplate.getResources().values()) {
245 if (filenames.contains(resource.getType())) {
246 handleNestedFile(translationContext, fileDataCollection, filteredFiles, referenced,
248 } else if (resource.getType()
249 .equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
251 resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
252 Object innerTypeDef = ((Map) resourceDef).get("type");
253 if (innerTypeDef instanceof String) {
254 String internalResourceType = (String) innerTypeDef;
255 if (filenames.contains(internalResourceType)) {
256 handleNestedFile(translationContext, fileDataCollection, filteredFiles,
258 internalResourceType);
266 fileDataCollection.addArtifactFiles(fileData);
267 filteredFiles.remove(fileData.getFile());
271 referenced.forEach(filteredFiles::remove);
272 if (!CollectionUtils.isEmpty(fileDataCollection.getBaseFile())) {
273 for (FileData fileData : fileDataCollection.getBaseFile()) {
274 filteredFiles.remove(fileData.getFile());
277 fileDataCollection.setAddOnFiles(filteredFiles.values());
278 return fileDataCollection;
281 private static void handleNestedFile(TranslationContext translationContext,
282 FileDataCollection fileDataCollection,
283 Map<String, FileData> filteredFiles, Set<String> referenced,
284 String nestedFileName) {
287 mdcDataDebugMessage.debugEntryMessage(null, null);
289 referenced.add(nestedFileName);
290 fileDataCollection.addNestedFiles(filteredFiles.get(nestedFileName));
291 translationContext.getNestedHeatsFiles().add(nestedFileName);
293 mdcDataDebugMessage.debugExitMessage(null, null);
296 private static Map<String, FileData> filterFileDataListByType(List<FileData> fileDataList,
297 Set<FileData.Type> typesToGet) {
298 Map<String, FileData> filtered = new HashMap<>();
299 fileDataList.stream().filter(file -> typesToGet.contains(file.getType()))
300 .forEach(file -> filtered.put(file.getFile(), file));
304 private static List<String> extractFilenamesFromFileDataList(Collection<FileData> fileDataList) {
305 return fileDataList.stream().map(FileData::getFile).collect(Collectors.toList());
309 * Extract attached resource id optional.
311 * @param translateTo the translate to
312 * @param propertyName the property name
313 * @return the optional
315 public static Optional<AttachedResourceId> extractAttachedResourceId(TranslateTo translateTo,
316 String propertyName) {
319 mdcDataDebugMessage.debugEntryMessage(null, null);
321 Object propertyValue = translateTo.getResource().getProperties().get(propertyName);
322 if (propertyValue == null) {
323 return Optional.empty();
326 mdcDataDebugMessage.debugExitMessage(null, null);
327 return extractAttachedResourceId(translateTo.getHeatFileName(),
328 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(), propertyValue);
332 * Extract attached resource id optional.
334 * @param heatFileName the heat file name
335 * @param heatOrchestrationTemplate the heat orchestration template
336 * @param context the context
337 * @param propertyValue the property value
338 * @return the optional
340 public static Optional<AttachedResourceId> extractAttachedResourceId(String heatFileName,
341 HeatOrchestrationTemplate heatOrchestrationTemplate,
342 TranslationContext context,
343 Object propertyValue) {
348 if (Objects.isNull(propertyValue)) {
349 return Optional.empty();
352 ReferenceType referenceType = ReferenceType.OTHER;
353 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
354 Map<String, Object> propMap = (Map) propertyValue;
355 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
356 entity = entry.getValue();
357 String key = entry.getKey();
360 referenceType = ReferenceType.GET_RESOURCE;
363 referenceType = ReferenceType.GET_PARAM;
366 referenceType = ReferenceType.GET_ATTR;
369 referenceType = ReferenceType.OTHER;
373 if (!FunctionTranslationFactory.getInstance(entry.getKey()).isPresent()) {
376 translatedId = FunctionTranslationFactory.getInstance(entry.getKey()).get()
377 .translateFunction(null, null, null, entry.getKey(), entry.getValue(), heatFileName,
378 heatOrchestrationTemplate, null, context);
380 if (translatedId instanceof String
381 && !FunctionTranslationHelper.isResourceSupported((String) translatedId)) {
386 translatedId = propertyValue;
387 entity = propertyValue;
390 return Optional.of(new AttachedResourceId(translatedId, entity, referenceType));
394 * Gets contrail attached heat resource id.
396 * @param attachedResource the attached resource
397 * @return the contrail attached heat resource id
399 public static Optional<String> getContrailAttachedHeatResourceId(
400 AttachedResourceId attachedResource) {
403 mdcDataDebugMessage.debugEntryMessage(null, null);
405 if (attachedResource == null) {
406 return Optional.empty();
409 if (attachedResource.isGetResource()) {
410 return Optional.of((String) attachedResource.getEntityId());
412 if (attachedResource.isGetAttr() && (attachedResource.getEntityId() instanceof List)
413 && ((List) attachedResource.getEntityId()).size() > 1
414 && ((List) attachedResource.getEntityId()).get(1).equals("fq_name")) {
415 return Optional.of((String) ((List) attachedResource.getEntityId()).get(0));
418 mdcDataDebugMessage.debugExitMessage(null, null);
419 return Optional.empty();
423 * Extract property optional.
425 * @param propertyValue the property value
426 * @return the optional
428 public static Optional<AttachedPropertyVal> extractProperty(Object propertyValue) {
430 mdcDataDebugMessage.debugEntryMessage(null, null);
431 Object attachedPropertyVal;
432 if (Objects.isNull(propertyValue)) {
433 return Optional.empty();
436 ReferenceType referenceType = ReferenceType.OTHER;
437 if (propertyValue instanceof Map && !((Map) propertyValue).isEmpty()) {
438 Map<String, Object> propMap = (Map) propertyValue;
439 Map.Entry<String, Object> entry = propMap.entrySet().iterator().next();
440 attachedPropertyVal = entry.getValue();
441 String key = entry.getKey();
444 referenceType = ReferenceType.GET_RESOURCE;
447 referenceType = ReferenceType.GET_PARAM;
450 referenceType = ReferenceType.GET_ATTR;
457 attachedPropertyVal = propertyValue;
460 mdcDataDebugMessage.debugExitMessage(null, null);
461 return Optional.of(new AttachedPropertyVal(attachedPropertyVal, referenceType));
467 * @param nodeTemplate the node template
468 * @param propertyKey the property key
470 public static void mapBoolean(NodeTemplate nodeTemplate, String propertyKey) {
471 mdcDataDebugMessage.debugEntryMessage(null, null);
473 Object value = nodeTemplate.getProperties().get(propertyKey);
474 if (value != null && !(value instanceof Map)) {
475 nodeTemplate.getProperties().put(propertyKey, HeatBoolean.eval(value));
478 mdcDataDebugMessage.debugExitMessage(null, null);
484 * @param nodeTemplate the node template
485 * @param propertyListKey the property list key
487 public static void mapBooleanList(NodeTemplate nodeTemplate, String propertyListKey) {
488 Object listValue = nodeTemplate.getProperties().get(propertyListKey);
489 if (listValue instanceof List) {
490 List booleanList = ((List) listValue);
491 for (int i = 0; i < booleanList.size(); i++) {
492 Object value = booleanList.get(i);
493 if (value != null && !(value instanceof Map)) {
494 booleanList.set(i, HeatBoolean.eval(value));
502 * Is yml file type boolean.
504 * @param filename the filename
505 * @return the boolean
507 public static boolean isYmlFileType(String filename) {
508 return (filename.indexOf("yaml") > 0 || filename.indexOf("yml") > 0);
512 * Is nested resource boolean.
514 * @param resource the resource
515 * @return the boolean
517 public static boolean isNestedResource(Resource resource) {
518 mdcDataDebugMessage.debugEntryMessage(null, null);
520 String resourceType = resource.getType();
522 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
523 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
524 if (!(((Map) resourceDef).get("type") instanceof String)) {
525 //currently only resource group which is poinitng to nested heat file is supported
526 //dynamic type is currently not supported
529 String internalResourceType = (String) ((Map) resourceDef).get("type");
530 if (isYamlFile(internalResourceType)) {
533 } else if (isYamlFile(resourceType)) {
537 mdcDataDebugMessage.debugExitMessage(null, null);
542 * Get nested heat file name in case of nested resource.
544 * @param resource the resource
545 * @return the nested heat file name
547 public static Optional<String> getNestedHeatFileName(Resource resource) {
548 mdcDataDebugMessage.debugEntryMessage(null, null);
550 if (!isNestedResource(resource)) {
551 return Optional.empty();
554 String resourceType = resource.getType();
556 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
557 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
558 String internalResourceType = (String) ((Map) resourceDef).get("type");
559 return Optional.of(internalResourceType);
562 mdcDataDebugMessage.debugExitMessage(null, null);
563 return Optional.of(resourceType);
569 * @param resource the resource
570 * @return the nested file
572 public static Optional<String> getNestedFile(Resource resource) {
575 mdcDataDebugMessage.debugEntryMessage(null, null);
577 if (!isNestedResource(resource)) {
578 return Optional.empty();
580 String resourceType = resource.getType();
581 if (resourceType.equals(HeatResourcesTypes.RESOURCE_GROUP_RESOURCE_TYPE.getHeatResource())) {
582 Object resourceDef = resource.getProperties().get(HeatConstants.RESOURCE_DEF_PROPERTY_NAME);
583 String internalResourceType = (String) ((Map) resourceDef).get("type");
585 mdcDataDebugMessage.debugExitMessage(null, null);
586 return Optional.of(internalResourceType);
588 mdcDataDebugMessage.debugExitMessage(null, null);
589 return Optional.of(resourceType);
593 private static boolean isYamlFile(String fileName) {
594 return fileName.endsWith(".yaml") || fileName.endsWith(".yml");
600 * @param heatOrchestrationTemplate the heat orchestration template
601 * @param resourceId the resource id
602 * @param heatFileName the heat file name
603 * @return the resource
605 public static Resource getResource(HeatOrchestrationTemplate heatOrchestrationTemplate,
606 String resourceId, String heatFileName) {
609 mdcDataDebugMessage.debugEntryMessage(null, null);
611 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
612 if (resource == null) {
613 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
614 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
615 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
616 throw new CoreException(
617 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
620 mdcDataDebugMessage.debugExitMessage(null, null);
628 * @param resourceId the resource id
629 * @param heatOrchestrationTemplate heat orchestration template
630 * @param heatFileName heat file name
631 * @return resource type
633 public static String getResourceType(String resourceId,
634 HeatOrchestrationTemplate heatOrchestrationTemplate,
635 String heatFileName) {
638 mdcDataDebugMessage.debugEntryMessage(null, null);
640 mdcDataDebugMessage.debugExitMessage(null, null);
641 return HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName)
646 * Is heat file nested boolean.
648 * @param translateTo the translate to
649 * @param heatFileName the heat file name
650 * @return the boolean
652 public static boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
653 return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
657 * Extract contrail get resource attached heat resource id optional.
659 * @param propertyValue the property value
660 * @return the optional
662 public static Optional<String> extractContrailGetResourceAttachedHeatResourceId(
663 Object propertyValue) {
666 mdcDataDebugMessage.debugEntryMessage(null, null);
668 if (propertyValue == null) {
669 return Optional.empty();
673 if (propertyValue instanceof Map) {
674 if (((Map) propertyValue).containsKey("get_attr")) {
675 value = ((Map) propertyValue).get("get_attr");
676 if (value instanceof List) {
677 if (((List) value).size() == 2 && ((List) value).get(1).equals("fq_name")) {
678 if (((List) value).get(0) instanceof String) {
679 return Optional.of((String) ((List) value).get(0));
681 logger.warn("invalid format of 'get_attr' function - " + propertyValue.toString());
685 } else if (((Map) propertyValue).containsKey("get_resource")) {
686 value = ((Map) propertyValue).get("get_resource");
687 if (value instanceof String) {
688 return Optional.of((String) value);
690 logger.warn("invalid format of 'get_resource' function - " + propertyValue.toString());
693 Collection<Object> valCollection = ((Map) propertyValue).values();
694 for (Object entryValue : valCollection) {
695 Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(entryValue);
696 if (ret.isPresent()) {
702 } else if (propertyValue instanceof List) {
703 for (Object prop : (List) propertyValue) {
704 Optional<String> ret = extractContrailGetResourceAttachedHeatResourceId(prop);
705 if (ret.isPresent()) {
711 mdcDataDebugMessage.debugExitMessage(null, null);
712 return Optional.empty();
716 * Gets tosca service model.
718 * @param context translation context
719 * @return the tosca service model
721 public static ToscaServiceModel getToscaServiceModel(TranslationContext context) {
722 mdcDataDebugMessage.debugEntryMessage(null, null);
723 mdcDataDebugMessage.debugExitMessage(null, null);
725 Map<String, String> metadata = new HashMap<>();
726 metadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
727 return getToscaServiceModel(context, metadata);
731 * Gets tosca service model.
733 * @param context translation context
734 * @param entryDefinitionMetadata template name of the entry definition servie template
735 * @return the tosca service model
737 public static ToscaServiceModel getToscaServiceModel(TranslationContext context,
738 Map<String, String> entryDefinitionMetadata) {
739 mdcDataDebugMessage.debugEntryMessage(null, null);
741 Map<String, ServiceTemplate> serviceTemplates =
742 new HashMap<>(context.getGlobalServiceTemplates());
743 Collection<ServiceTemplate> tmpServiceTemplates =
744 context.getTranslatedServiceTemplates().values();
745 for (ServiceTemplate serviceTemplate : tmpServiceTemplates) {
746 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplate);
749 mdcDataDebugMessage.debugExitMessage(null, null);
750 return new ToscaServiceModel(null, serviceTemplates,
751 ToscaUtil.getServiceTemplateFileName(entryDefinitionMetadata));
755 * Gets service template from context.
757 * @param serviceTemplateFileName the service template file name
758 * @param context the context
759 * @return the service template from context
761 public static Optional<ServiceTemplate> getServiceTemplateFromContext(
762 String serviceTemplateFileName, TranslationContext context) {
765 mdcDataDebugMessage.debugEntryMessage(null, null);
767 for (ServiceTemplate serviceTemplate : context.getTranslatedServiceTemplates().values()) {
768 if (ToscaUtil.getServiceTemplateFileName(serviceTemplate).equals(serviceTemplateFileName)) {
769 mdcDataDebugMessage.debugExitMessage(null, null);
770 return Optional.of(serviceTemplate);
774 mdcDataDebugMessage.debugExitMessage(null, null);
775 return Optional.empty();
779 * Adding binding requerment from port node template to compute node template.
781 * @param computeNodeTemplateId compute node template id
782 * @param portNodeTemplate port node template
784 public static void addBindingReqFromPortToCompute(String computeNodeTemplateId,
785 NodeTemplate portNodeTemplate) {
788 mdcDataDebugMessage.debugEntryMessage(null, null);
790 RequirementAssignment requirementAssignment = new RequirementAssignment();
791 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
792 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
793 requirementAssignment.setNode(computeNodeTemplateId);
794 DataModelUtil.addRequirementAssignment(portNodeTemplate, ToscaConstants.BINDING_REQUIREMENT_ID,
795 requirementAssignment);
797 mdcDataDebugMessage.debugExitMessage(null, null);
801 * Adding link requerment from port node template to network node template.
803 * @param portNodeTemplate port node template
804 * @param networkTranslatedId network node template id
806 public static RequirementAssignment addLinkReqFromPortToNetwork(NodeTemplate portNodeTemplate,
807 String networkTranslatedId) {
810 mdcDataDebugMessage.debugEntryMessage(null, null);
812 RequirementAssignment requirement = new RequirementAssignment();
813 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
814 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
815 requirement.setNode(networkTranslatedId);
816 DataModelUtil.addRequirementAssignment(portNodeTemplate,
817 ToscaConstants.LINK_REQUIREMENT_ID, requirement);
819 mdcDataDebugMessage.debugExitMessage(null, null);
825 * Adding binding requerment from sub interface node template to interface (port) node template.
827 * @param subInterfaceNodeTemplate sub interface template
828 * @param interfaceTranslatedId interface node template id
830 public static void addBindingReqFromSubInterfaceToInterface(
831 NodeTemplate subInterfaceNodeTemplate, String interfaceTranslatedId) {
834 mdcDataDebugMessage.debugEntryMessage(null, null);
836 RequirementAssignment requirement = new RequirementAssignment();
837 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_BINDABLE);
838 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_BINDS_TO);
839 requirement.setNode(interfaceTranslatedId);
841 .addRequirementAssignment(subInterfaceNodeTemplate,
842 ToscaConstants.BINDING_REQUIREMENT_ID, requirement);
844 mdcDataDebugMessage.debugExitMessage(null, null);
848 * Get property Parameter Name Value.
850 * @param property property
851 * @return Parameter name in case the property include "get_param" function
853 public static Optional<String> getPropertyParameterNameValue(Object property) {
854 if (Objects.isNull(property)) {
855 return Optional.empty();
857 Optional<AttachedPropertyVal> extractedProperty = extractProperty(property);
858 if (extractedProperty.isPresent()) {
859 return getParameterName(extractedProperty.get());
861 return Optional.empty();
864 private static Optional<String> getParameterName(AttachedPropertyVal extractedProperty) {
865 if (!extractedProperty.isGetParam()) {
866 return Optional.empty();
868 Object getParamFuncValue = extractedProperty.getPropertyValue();
869 if (getParamFuncValue instanceof String) {
870 return Optional.of((String) getParamFuncValue);
872 return Optional.of((String) ((List) getParamFuncValue).get(0));
876 public static String getToscaPropertyName(TranslationContext context, String heatResourceType,
877 String heatPropertyName) {
878 return context.getElementMapping(heatResourceType, Constants.PROP, heatPropertyName);
882 * Gets tosca property name.
884 * @param translateTo the translate to
885 * @param heatPropertyName the heat property name
886 * @return the tosca property name
888 public static String getToscaPropertyName(TranslateTo translateTo, String heatPropertyName) {
889 return translateTo.getContext()
890 .getElementMapping(translateTo.getResource().getType(), Constants.PROP, heatPropertyName);
894 * Gets tosca attribute name.
896 * @param context the context
897 * @param heatResourceType the heat resource type
898 * @param heatAttrName the heat attr name
899 * @return the tosca attribute name
901 public static String getToscaAttributeName(TranslationContext context, String heatResourceType,
902 String heatAttrName) {
903 return context.getElementMapping(heatResourceType, Constants.ATTR, heatAttrName);
907 * Gets tosca attribute name.
909 * @param translateTo the translate to
910 * @param heatAttrName the heat attr name
911 * @return the tosca attribute name
913 public static String getToscaAttributeName(TranslateTo translateTo, String heatAttrName) {
914 return translateTo.getContext()
915 .getElementMapping(translateTo.getResource().getType(), Constants.ATTR, heatAttrName);
919 * Create init substitution service template service template.
921 * @param templateName the template name
922 * @return the service template
924 public static ServiceTemplate createInitSubstitutionServiceTemplate(String templateName) {
925 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
926 Map<String, String> templateMetadata = new HashMap<>();
927 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, templateName);
928 nestedSubstitutionServiceTemplate.setMetadata(templateMetadata);
929 nestedSubstitutionServiceTemplate
930 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
931 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
932 List<Map<String, Import>> globalTypesImportList =
933 GlobalTypesGenerator.getGlobalTypesImportList();
934 globalTypesImportList.addAll(
935 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
936 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
937 return nestedSubstitutionServiceTemplate;
941 * Create init global substitution service template service template.
943 * @return the service template
945 public static ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
946 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
947 Map<String, String> templateMetadata = new HashMap<>();
948 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
949 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
950 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
951 globalSubstitutionServiceTemplate
952 .setImports(GlobalTypesGenerator.getGlobalTypesImportList());
953 globalSubstitutionServiceTemplate
954 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
955 return globalSubstitutionServiceTemplate;
959 * Create substitution node type node type.
961 * @param substitutionServiceTemplate the substitution service template
962 * @return the node type
964 public NodeType createSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate) {
965 NodeType substitutionNodeType = new NodeType();
966 substitutionNodeType.setDerived_from(ToscaNodeType.ABSTRACT_SUBSTITUTE);
967 substitutionNodeType.setDescription(substitutionServiceTemplate.getDescription());
969 .setProperties(manageSubstitutionNodeTypeProperties(substitutionServiceTemplate));
971 .setAttributes(manageSubstitutionNodeTypeAttributes(substitutionServiceTemplate));
972 return substitutionNodeType;
975 private Map<String, PropertyDefinition> manageSubstitutionNodeTypeProperties(
976 ServiceTemplate substitutionServiceTemplate) {
977 mdcDataDebugMessage.debugEntryMessage(null, null);
979 Map<String, PropertyDefinition> substitutionNodeTypeProperties = new HashMap<>();
980 Map<String, ParameterDefinition> properties =
981 substitutionServiceTemplate.getTopology_template().getInputs();
982 if (properties == null) {
983 mdcDataDebugMessage.debugExitMessage(null, null);
987 PropertyDefinition propertyDefinition;
988 String toscaPropertyName;
989 for (Map.Entry<String, ParameterDefinition> entry : properties.entrySet()) {
990 toscaPropertyName = entry.getKey();
991 propertyDefinition = new PropertyDefinition();
992 ParameterDefinition parameterDefinition =
993 substitutionServiceTemplate.getTopology_template().getInputs().get(toscaPropertyName);
994 propertyDefinition.setType(parameterDefinition.getType());
995 propertyDefinition.setDescription(parameterDefinition.getDescription());
996 propertyDefinition.setRequired(parameterDefinition.getRequired());
997 propertyDefinition.set_default(parameterDefinition.get_default());
998 propertyDefinition.setConstraints(parameterDefinition.getConstraints());
999 propertyDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1000 propertyDefinition.setStatus(parameterDefinition.getStatus());
1001 substitutionNodeTypeProperties.put(toscaPropertyName, propertyDefinition);
1004 mdcDataDebugMessage.debugExitMessage(null, null);
1005 return substitutionNodeTypeProperties;
1008 private Map<String, AttributeDefinition> manageSubstitutionNodeTypeAttributes(
1009 ServiceTemplate substitutionServiceTemplate) {
1012 mdcDataDebugMessage.debugEntryMessage(null, null);
1014 Map<String, AttributeDefinition> substitutionNodeTypeAttributes = new HashMap<>();
1015 Map<String, ParameterDefinition> attributes =
1016 substitutionServiceTemplate.getTopology_template().getOutputs();
1017 if (attributes == null) {
1018 mdcDataDebugMessage.debugExitMessage(null, null);
1021 AttributeDefinition attributeDefinition;
1022 String toscaAttributeName;
1024 for (Map.Entry<String, ParameterDefinition> entry : attributes.entrySet()) {
1025 attributeDefinition = new AttributeDefinition();
1026 toscaAttributeName = entry.getKey();
1027 ParameterDefinition parameterDefinition =
1028 substitutionServiceTemplate.getTopology_template().getOutputs().get(toscaAttributeName);
1029 if (parameterDefinition.getType() != null && !parameterDefinition.getType().isEmpty()) {
1030 attributeDefinition.setType(parameterDefinition.getType());
1032 attributeDefinition.setType(PropertyType.STRING.getDisplayName());
1034 attributeDefinition.setDescription(parameterDefinition.getDescription());
1035 attributeDefinition.set_default(parameterDefinition.get_default());
1036 attributeDefinition.setEntry_schema(parameterDefinition.getEntry_schema());
1037 attributeDefinition.setStatus(parameterDefinition.getStatus());
1038 substitutionNodeTypeAttributes.put(toscaAttributeName, attributeDefinition);
1041 mdcDataDebugMessage.debugExitMessage(null, null);
1042 return substitutionNodeTypeAttributes;
1047 * Create and add substitution mapping to the nested substitution service template, and update
1048 * the subtitution node type accordingly with the exposed requerments and capabilities
1050 * @param context the translation context
1051 * @param substitutionNodeTypeKey the substitution node type key
1052 * @param nestedSubstitutionServiceTemplate the nested substitution service template
1053 * @param substitutionNodeType the substitution node type
1055 public static void handleSubstitutionMapping(
1056 TranslationContext context,
1057 String substitutionNodeTypeKey,
1058 ServiceTemplate nestedSubstitutionServiceTemplate,
1059 NodeType substitutionNodeType) {
1060 Map<String, Map<String, List<String>>> substitutionMapping =
1061 getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
1062 nestedSubstitutionServiceTemplate, context);
1063 //add substitution mapping after capability and requirement expose calculation
1064 nestedSubstitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
1065 createSubstitutionTemplateSubMapping(substitutionNodeTypeKey,
1066 substitutionNodeType, substitutionMapping));
1070 * Gets node type with flat hierarchy.
1072 * @param nodeTypeId the node type id
1073 * @param serviceTemplate the service template
1074 * @param context the context
1075 * @return the node type with flat hierarchy
1077 public static NodeType getNodeTypeWithFlatHierarchy(String nodeTypeId,
1078 ServiceTemplate serviceTemplate,
1079 TranslationContext context) {
1080 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
1081 ToscaServiceModel toscaServiceModel = HeatToToscaUtil
1082 .getToscaServiceModel(context, serviceTemplate.getMetadata());
1083 NodeType flatNodeType = (NodeType) toscaAnalyzerService
1084 .getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeTypeId, serviceTemplate, toscaServiceModel);
1085 return flatNodeType;
1089 * Create substitution node template node template.
1091 * @param translateTo the translate to
1092 * @param templateName the template name
1093 * @param substitutionNodeTypeKey the substitution node type key
1094 * @return the node template
1096 public NodeTemplate createSubstitutionNodeTemplate(TranslateTo translateTo, String templateName,
1097 String substitutionNodeTypeKey) {
1098 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1099 List<String> directiveList = new ArrayList<>();
1100 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1101 substitutionNodeTemplate.setDirectives(directiveList);
1102 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1103 substitutionNodeTemplate.setProperties(
1104 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
1106 return substitutionNodeTemplate;
1110 * Create abstract substitution node template.
1112 * @param translateTo the translate to
1113 * @param templateName the template name
1114 * @param substitutionNodeTypeKey the substitution node type key
1115 * @return the abstract substitute node template
1117 public static NodeTemplate createAbstractSubstitutionNodeTemplate(
1118 TranslateTo translateTo,
1119 String templateName,
1120 String substitutionNodeTypeKey) {
1121 NodeTemplate substitutionNodeTemplate = new NodeTemplate();
1122 List<String> directiveList = new ArrayList<>();
1123 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
1124 substitutionNodeTemplate.setDirectives(directiveList);
1125 substitutionNodeTemplate.setType(substitutionNodeTypeKey);
1126 substitutionNodeTemplate.setProperties(
1127 managerSubstitutionNodeTemplateProperties(translateTo, substitutionNodeTemplate,
1129 return substitutionNodeTemplate;
1134 * Checks if the source and target resource is a valid candidate for adding tosca dependency
1137 * @param heatOrchestrationTemplate the heat orchestration template
1138 * @param sourceResource the source resource
1139 * @param targetResource the target resource
1140 * @param dependencyEntity the dependency entity
1141 * @return true if the candidate resources are a valid combination for the dependency relationship
1142 * and false otherwise
1144 public static boolean isValidDependsOnCandidate(HeatOrchestrationTemplate
1145 heatOrchestrationTemplate,
1146 Resource sourceResource,
1147 Resource targetResource,
1148 ConsolidationEntityType dependencyEntity,
1149 TranslationContext context) {
1151 .setEntityType(heatOrchestrationTemplate, sourceResource, targetResource, context);
1152 ConsolidationEntityType sourceEntityType = dependencyEntity.getSourceEntityType();
1153 ConsolidationEntityType targetEntityType = dependencyEntity.getTargetEntityType();
1155 //Ignore Compute->Port, Compute->volume, Compute->Compute and Compute->VFC Nested relationships
1156 if (sourceEntityType == ConsolidationEntityType.COMPUTE) {
1157 if (targetEntityType == ConsolidationEntityType.COMPUTE
1158 || targetEntityType == ConsolidationEntityType.VOLUME
1159 || targetEntityType == ConsolidationEntityType.PORT
1160 || targetEntityType == ConsolidationEntityType.VFC_NESTED) {
1164 //Ignore Port->Compute, Port->volume, Port->Port and Port->VFC Nested relationships
1165 if (sourceEntityType == ConsolidationEntityType.PORT) {
1166 if (targetEntityType == ConsolidationEntityType.COMPUTE
1167 || targetEntityType == ConsolidationEntityType.VOLUME
1168 || targetEntityType == ConsolidationEntityType.PORT
1169 || targetEntityType == ConsolidationEntityType.VFC_NESTED) {
1174 //Ignore Volume->Compute, Volume->Volume, Volume->Port and Volume->VFC Nested relationships
1175 if (sourceEntityType == ConsolidationEntityType.VOLUME) {
1176 if (targetEntityType == ConsolidationEntityType.COMPUTE
1177 || targetEntityType == ConsolidationEntityType.VOLUME
1178 || targetEntityType == ConsolidationEntityType.PORT
1179 || targetEntityType == ConsolidationEntityType.VFC_NESTED) {
1184 //Ignore VFC Nested->Compute, VFC Nested->Volume, VFC Nested->Port and
1185 // VFC Nested->VFC Nested relationships
1186 if (sourceEntityType == ConsolidationEntityType.VFC_NESTED) {
1187 if (targetEntityType == ConsolidationEntityType.COMPUTE
1188 || targetEntityType == ConsolidationEntityType.VOLUME
1189 || targetEntityType == ConsolidationEntityType.PORT
1190 || targetEntityType == ConsolidationEntityType.VFC_NESTED) {
1197 private static Map<String, Object> managerSubstitutionNodeTemplateProperties(
1198 TranslateTo translateTo,
1200 String templateName) {
1201 mdcDataDebugMessage.debugEntryMessage(null, null);
1203 Map<String, Object> substitutionProperties = new HashMap<>();
1204 Map<String, Object> heatProperties = translateTo.getResource().getProperties();
1205 if (Objects.nonNull(heatProperties)) {
1206 for (Map.Entry<String, Object> entry : heatProperties.entrySet()) {
1207 Object property = TranslatorHeatToToscaPropertyConverter
1208 .getToscaPropertyValue(translateTo.getServiceTemplate(),
1209 translateTo.getTranslatedId(), entry.getKey(),
1210 entry.getValue(), null, translateTo.getHeatFileName(),
1211 translateTo.getHeatOrchestrationTemplate(), template, translateTo.getContext());
1212 substitutionProperties.put(entry.getKey(), property);
1216 mdcDataDebugMessage.debugExitMessage(null, null);
1217 return addAbstractSubstitutionProperty(templateName, substitutionProperties);
1220 private static Map<String, Object> addAbstractSubstitutionProperty(String templateName,
1222 substitutionProperties) {
1225 mdcDataDebugMessage.debugEntryMessage(null, null);
1227 Map<String, Object> innerProps = new HashMap<>();
1228 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
1229 ToscaUtil.getServiceTemplateFileName(templateName));
1230 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
1232 mdcDataDebugMessage.debugExitMessage(null, null);
1233 return substitutionProperties;
1236 private static SubstitutionMapping createSubstitutionTemplateSubMapping(
1238 NodeType substitutionNodeType,
1239 Map<String, Map<String, List<String>>> mapping) {
1240 mdcDataDebugMessage.debugEntryMessage(null, null);
1241 SubstitutionMapping substitutionMapping = new SubstitutionMapping();
1242 substitutionMapping.setNode_type(nodeTypeKey);
1243 substitutionMapping.setCapabilities(
1244 manageCapabilityMapping(substitutionNodeType.getCapabilities(), mapping.get("capability")));
1245 substitutionMapping.setRequirements(
1246 manageRequirementMapping(substitutionNodeType.getRequirements(),
1247 mapping.get("requirement")));
1249 mdcDataDebugMessage.debugExitMessage(null, null);
1250 return substitutionMapping;
1253 private static Map<String, List<String>> manageRequirementMapping(
1254 List<Map<String, RequirementDefinition>> requirementList,
1255 Map<String, List<String>> requirementSubstitutionMapping) {
1256 mdcDataDebugMessage.debugEntryMessage(null, null);
1258 if (requirementList == null) {
1261 Map<String, List<String>> requirementMapping = new HashMap<>();
1262 String requirementKey;
1263 List<String> requirementMap;
1264 for (Map<String, RequirementDefinition> requirementDefMap : requirementList) {
1265 for (Map.Entry<String, RequirementDefinition> entry : requirementDefMap.entrySet()) {
1266 requirementKey = entry.getKey();
1267 requirementMap = requirementSubstitutionMapping.get(requirementKey);
1268 requirementMapping.put(requirementKey, requirementMap);
1272 mdcDataDebugMessage.debugExitMessage(null, null);
1273 return requirementMapping;
1276 private static Map<String, List<String>> manageCapabilityMapping(
1277 Map<String, CapabilityDefinition> capabilities,
1278 Map<String, List<String>> capabilitySubstitutionMapping) {
1279 mdcDataDebugMessage.debugEntryMessage(null, null);
1281 if (capabilities == null) {
1282 mdcDataDebugMessage.debugExitMessage(null, null);
1286 Map<String, List<String>> capabilityMapping = new HashMap<>();
1287 String capabilityKey;
1288 List<String> capabilityMap;
1289 for (Map.Entry<String, CapabilityDefinition> entry : capabilities.entrySet()) {
1290 capabilityKey = entry.getKey();
1291 capabilityMap = capabilitySubstitutionMapping.get(capabilityKey);
1292 capabilityMapping.put(capabilityKey, capabilityMap);
1295 mdcDataDebugMessage.debugExitMessage(null, null);
1296 return capabilityMapping;
1299 private static Map<String, Map<String, List<String>>>
1300 getSubstitutionNodeTypeExposedConnectionPoints(NodeType substitutionNodeType,
1301 ServiceTemplate substitutionServiceTemplate,
1302 TranslationContext context) {
1303 mdcDataDebugMessage.debugEntryMessage(null, null);
1305 Map<String, NodeTemplate> nodeTemplates =
1306 substitutionServiceTemplate.getTopology_template().getNode_templates();
1307 String nodeTemplateId;
1308 NodeTemplate nodeTemplate;
1310 Map<String, Map<String, List<String>>> substitutionMapping = new HashMap<>();
1311 if (nodeTemplates == null) {
1312 return substitutionMapping;
1315 Map<String, List<String>> capabilitySubstitutionMapping = new HashMap<>();
1316 Map<String, List<String>> requirementSubstitutionMapping = new HashMap<>();
1317 substitutionMapping.put("capability", capabilitySubstitutionMapping);
1318 substitutionMapping.put("requirement", requirementSubstitutionMapping);
1319 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinition;
1320 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment;
1321 List<Map<String, RequirementDefinition>> exposedRequirementsDefinition;
1322 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinition =
1324 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition = new HashMap<>();
1325 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition;
1327 for (Map.Entry<String, NodeTemplate> entry : nodeTemplates.entrySet()) {
1328 nodeTemplateId = entry.getKey();
1329 nodeTemplate = entry.getValue();
1330 nodeType = nodeTemplate.getType();
1333 nodeTypeRequirementsDefinition =
1334 getNodeTypeReqs(nodeType, nodeTemplateId, substitutionServiceTemplate,
1335 requirementSubstitutionMapping, context);
1336 nodeTemplateRequirementsAssignment = DataModelUtil.getNodeTemplateRequirements(nodeTemplate);
1337 fullFilledRequirementsDefinition.put(nodeTemplateId, nodeTemplateRequirementsAssignment);
1338 //set substitution node type requirements
1339 exposedRequirementsDefinition = calculateExposedRequirements(nodeTypeRequirementsDefinition,
1340 nodeTemplateRequirementsAssignment);
1341 addSubstitutionNodeTypeRequirements(substitutionNodeType, exposedRequirementsDefinition,
1345 addNodeTypeCapabilitiesToSubMapping(nodeTypeCapabilitiesDefinition,
1346 capabilitySubstitutionMapping, nodeType,
1347 nodeTemplateId, substitutionServiceTemplate, context);
1350 exposedCapabilitiesDefinition = calculateExposedCapabilities(nodeTypeCapabilitiesDefinition,
1351 fullFilledRequirementsDefinition);
1352 DataModelUtil.addNodeTypeCapabilitiesDef(substitutionNodeType, exposedCapabilitiesDefinition);
1354 mdcDataDebugMessage.debugExitMessage(null, null);
1355 return substitutionMapping;
1358 private static Map<String, CapabilityDefinition> calculateExposedCapabilities(
1359 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1360 Map<String, Map<String, RequirementAssignment>> fullFilledRequirementsDefinitionMap) {
1363 mdcDataDebugMessage.debugEntryMessage(null, null);
1365 String capabilityKey;
1368 for (Map.Entry<String, Map<String, RequirementAssignment>> entry :
1369 fullFilledRequirementsDefinitionMap.entrySet()) {
1370 for (Map.Entry<String, RequirementAssignment> fullFilledEntry : entry.getValue().entrySet()) {
1372 capability = fullFilledEntry.getValue().getCapability();
1373 fullFilledEntry.getValue().getOccurrences();
1374 node = fullFilledEntry.getValue().getNode();
1375 capabilityKey = capability + "_" + node;
1376 CapabilityDefinition capabilityDefinition = nodeTypeCapabilitiesDefinition.get(
1378 if (capabilityDefinition != null) {
1379 CapabilityDefinition clonedCapabilityDefinition = capabilityDefinition.clone();
1380 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityDefinition.clone());
1381 if (evaluateCapabilityFulfillment(clonedCapabilityDefinition)) {
1382 nodeTypeCapabilitiesDefinition.remove(capabilityKey);
1384 nodeTypeCapabilitiesDefinition.put(capabilityKey, clonedCapabilityDefinition);
1390 Map<String, CapabilityDefinition> exposedCapabilitiesDefinition = new HashMap<>();
1391 for (Map.Entry<String, CapabilityDefinition> entry : nodeTypeCapabilitiesDefinition
1393 exposedCapabilitiesDefinition.put(entry.getKey(), entry.getValue());
1396 mdcDataDebugMessage.debugExitMessage(null, null);
1397 return exposedCapabilitiesDefinition;
1400 private static void addNodeTypeCapabilitiesToSubMapping(
1401 Map<String, CapabilityDefinition> nodeTypeCapabilitiesDefinition,
1402 Map<String, List<String>> capabilitySubstitutionMapping, String type, String templateName,
1403 ServiceTemplate serviceTemplate, TranslationContext context) {
1404 mdcDataDebugMessage.debugEntryMessage(null, null);
1406 NodeType flatNodeType =
1407 getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1408 String capabilityKey;
1409 List<String> capabilityMapping;
1410 if (flatNodeType.getCapabilities() != null) {
1411 for (Map.Entry<String, CapabilityDefinition> capabilityNodeEntry : flatNodeType
1414 capabilityKey = capabilityNodeEntry.getKey() + "_" + templateName;
1415 nodeTypeCapabilitiesDefinition.put(capabilityKey, capabilityNodeEntry.getValue().clone());
1416 capabilityMapping = new ArrayList<>();
1417 capabilityMapping.add(templateName);
1418 capabilityMapping.add(capabilityNodeEntry.getKey());
1419 capabilitySubstitutionMapping.put(capabilityKey, capabilityMapping);
1422 mdcDataDebugMessage.debugExitMessage(null, null);
1425 private static void addSubstitutionNodeTypeRequirements(NodeType substitutionNodeType,
1426 List<Map<String, RequirementDefinition>>
1428 String templateName) {
1429 mdcDataDebugMessage.debugEntryMessage(null, null);
1431 if (requirementsList == null || requirementsList.size() == 0) {
1435 if (substitutionNodeType.getRequirements() == null) {
1436 substitutionNodeType.setRequirements(new ArrayList<>());
1439 for (Map<String, RequirementDefinition> requirementDef : requirementsList) {
1440 for (Map.Entry<String, RequirementDefinition> entry : requirementDef.entrySet()) {
1441 Map<String, RequirementDefinition> requirementMap = new HashMap<>();
1442 requirementMap.put(entry.getKey() + "_" + templateName, entry.getValue().clone());
1443 substitutionNodeType.getRequirements().add(requirementMap);
1447 mdcDataDebugMessage.debugExitMessage(null, null);
1450 private static List<Map<String, RequirementDefinition>> getNodeTypeReqs(
1452 String templateName,
1453 ServiceTemplate serviceTemplate,
1454 Map<String, List<String>> requirementSubstitutionMapping,
1455 TranslationContext context) {
1456 mdcDataDebugMessage.debugEntryMessage(null, null);
1457 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
1458 NodeType flatNodeType =
1459 getNodeTypeWithFlatHierarchy(type, serviceTemplate, context);
1460 List<String> requirementMapping;
1462 if (flatNodeType.getRequirements() != null) {
1463 for (Map<String, RequirementDefinition> requirementMap : flatNodeType.getRequirements()) {
1464 for (Map.Entry<String, RequirementDefinition> requirementNodeEntry : requirementMap
1466 ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
1467 RequirementDefinition requirementNodeEntryValue = toscaExtensionYamlUtil
1468 .yamlToObject(toscaExtensionYamlUtil.objectToYaml(requirementNodeEntry.getValue()),
1469 RequirementDefinition.class);
1470 if (requirementNodeEntryValue.getOccurrences() == null) {
1471 requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
1473 Map<String, RequirementDefinition> requirementDef = new HashMap<>();
1474 requirementDef.put(requirementNodeEntry.getKey(), requirementNodeEntryValue);
1475 DataModelUtil.addRequirementToList(requirementList, requirementDef);
1476 requirementMapping = new ArrayList<>();
1477 requirementMapping.add(templateName);
1478 requirementMapping.add(requirementNodeEntry.getKey());
1479 requirementSubstitutionMapping
1480 .put(requirementNodeEntry.getKey() + "_" + templateName, requirementMapping);
1481 if (requirementNodeEntryValue.getNode() == null) {
1482 requirementNodeEntryValue.setOccurrences(new Object[]{1, 1});
1488 mdcDataDebugMessage.debugExitMessage(null, null);
1489 return requirementList;
1492 private static List<Map<String, RequirementDefinition>> calculateExposedRequirements(
1493 List<Map<String, RequirementDefinition>> nodeTypeRequirementsDefinitionList,
1494 Map<String, RequirementAssignment> nodeTemplateRequirementsAssignment) {
1495 mdcDataDebugMessage.debugEntryMessage(null, null);
1497 if (nodeTypeRequirementsDefinitionList == null) {
1500 for (Map.Entry<String, RequirementAssignment> entry : nodeTemplateRequirementsAssignment
1502 if (entry.getValue().getNode() != null) {
1503 Optional<RequirementDefinition> requirementDefinition =
1504 DataModelUtil.getRequirementDefinition(nodeTypeRequirementsDefinitionList, entry
1506 RequirementDefinition cloneRequirementDefinition;
1507 if (requirementDefinition.isPresent()) {
1508 cloneRequirementDefinition = requirementDefinition.get().clone();
1509 if (!evaluateRequirementFulfillment(cloneRequirementDefinition)) {
1510 CommonMethods.mergeEntryInList(entry.getKey(), cloneRequirementDefinition,
1511 nodeTypeRequirementsDefinitionList);
1513 DataModelUtil.removeRequirementsDefinition(nodeTypeRequirementsDefinitionList, entry
1518 for (Map<String, RequirementDefinition> nodeTypeRequirementsMap :
1519 nodeTypeRequirementsDefinitionList) {
1520 Object max = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
1521 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
1522 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[1] : 1;
1523 Object min = nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences() != null
1524 && nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences().length > 0
1525 ? nodeTypeRequirementsMap.get(entry.getKey()).getOccurrences()[0] : 1;
1526 nodeTypeRequirementsMap.get(entry.getKey()).setOccurrences(new Object[]{min, max});
1531 mdcDataDebugMessage.debugExitMessage(null, null);
1532 return nodeTypeRequirementsDefinitionList;
1535 private static boolean evaluateRequirementFulfillment(RequirementDefinition
1536 requirementDefinition) {
1537 Object[] occurrences = requirementDefinition.getOccurrences();
1538 if (occurrences == null) {
1539 requirementDefinition.setOccurrences(new Object[]{1, 1});
1542 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
1546 if (occurrences[1].equals(1)) {
1549 occurrences[1] = (Integer) occurrences[1] - 1;
1553 private static boolean evaluateCapabilityFulfillment(CapabilityDefinition capabilityDefinition) {
1555 Object[] occurrences = capabilityDefinition.getOccurrences();
1556 if (occurrences == null) {
1557 capabilityDefinition.setOccurrences(new Object[]{1, ToscaConstants.UNBOUNDED});
1560 if (occurrences[1].equals(ToscaConstants.UNBOUNDED)) {
1564 if (occurrences[1].equals(1)) {
1567 occurrences[1] = (Integer) occurrences[1] - 1;
1572 * Fetch global substitution service template service template.
1574 * @param serviceTemplate the service template
1575 * @param context the context
1576 * @return the service template
1578 public static ServiceTemplate fetchGlobalSubstitutionServiceTemplate(
1579 ServiceTemplate serviceTemplate,
1580 TranslationContext context) {
1581 ServiceTemplate globalSubstitutionServiceTemplate =
1582 context.getTranslatedServiceTemplates()
1583 .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1584 if (globalSubstitutionServiceTemplate == null) {
1585 globalSubstitutionServiceTemplate =
1586 HeatToToscaUtil.createInitGlobalSubstitutionServiceTemplate();
1587 context.getTranslatedServiceTemplates()
1588 .put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
1589 globalSubstitutionServiceTemplate);
1591 boolean isImportAddedToServiceTemplate =
1592 DataModelUtil.isImportAddedToServiceTemplate(serviceTemplate.getImports(), Constants
1593 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
1594 if (!isImportAddedToServiceTemplate) {
1595 serviceTemplate.getImports()
1597 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
1599 return globalSubstitutionServiceTemplate;
1602 public static List<Map<String, Import>> createImportList(String templateName) {
1603 List<Map<String, Import>> imports = new ArrayList<>();
1604 Map<String, Import> importsMap = new HashMap<>();
1605 importsMap.put(templateName, HeatToToscaUtil.createServiceTemplateImport(templateName));
1606 imports.add(importsMap);
1611 * Create service template import import.
1613 * @param serviceTemplate the service template
1614 * @return the import
1616 public static Import createServiceTemplateImport(ServiceTemplate serviceTemplate) {
1617 Import serviceTemplateImport = new Import();
1618 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(serviceTemplate));
1619 return serviceTemplateImport;
1623 * Create service template import import.
1625 * @param metadataTemplateName the service template name
1626 * @return the import
1628 public static Import createServiceTemplateImport(String metadataTemplateName) {
1629 Import serviceTemplateImport = new Import();
1630 serviceTemplateImport.setFile(ToscaUtil.getServiceTemplateFileName(metadataTemplateName));
1631 return serviceTemplateImport;
1634 public static ToscaServiceModel createToscaServiceModel(ServiceTemplate
1635 entryDefinitionServiceTemplate,
1636 TranslationContext translationContext) {
1639 mdcDataDebugMessage.debugEntryMessage(null, null);
1641 mdcDataDebugMessage.debugExitMessage(null, null);
1642 return new ToscaServiceModel(getCsarArtifactFiles(translationContext),
1643 getServiceTemplates(translationContext),
1644 ToscaUtil.getServiceTemplateFileName(entryDefinitionServiceTemplate));
1647 private static FileContentHandler getCsarArtifactFiles(TranslationContext translationContext) {
1649 mdcDataDebugMessage.debugEntryMessage(null, null);
1651 FileContentHandler artifactFiles = new FileContentHandler();
1652 artifactFiles.setFiles(translationContext.getFiles());
1653 artifactFiles.setFiles(translationContext.getExternalArtifacts());
1655 HeatTreeManager heatTreeManager =
1656 HeatTreeManagerUtil.initHeatTreeManager(translationContext.getFiles());
1657 heatTreeManager.createTree();
1658 ValidationStructureList validationStructureList =
1659 new ValidationStructureList(heatTreeManager.getTree());
1660 byte[] validationStructureFile =
1661 FileUtils.convertToBytes(validationStructureList, FileUtils.FileExtension.JSON);
1662 artifactFiles.addFile("HEAT.meta", validationStructureFile);
1664 mdcDataDebugMessage.debugExitMessage(null, null);
1665 return artifactFiles;
1669 private static Map<String, ServiceTemplate> getServiceTemplates(TranslationContext
1670 translationContext) {
1673 mdcDataDebugMessage.debugEntryMessage(null, null);
1675 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
1676 serviceTemplates.addAll(GlobalTypesGenerator.getGlobalTypesServiceTemplate().values());
1677 serviceTemplates.addAll(translationContext.getTranslatedServiceTemplates().values());
1678 Map<String, ServiceTemplate> serviceTemplatesMap = new HashMap<>();
1680 for (ServiceTemplate template : serviceTemplates) {
1681 serviceTemplatesMap.put(ToscaUtil.getServiceTemplateFileName(template), template);
1684 mdcDataDebugMessage.debugExitMessage(null, null);
1685 return serviceTemplatesMap;