3 * * ============LICENSE_START=======================================================
4 * * Copyright (C) 2019 Nordix Foundation.
5 * * ================================================================================
6 * * Licensed under the Apache License, Version 2.0 (the "License");
7 * * you may not use this file except in compliance with the License.
8 * * You may obtain a copy of the License at
10 * * http://www.apache.org/licenses/LICENSE-2.0
12 * * Unless required by applicable law or agreed to in writing, software
13 * * distributed under the License is distributed on an "AS IS" BASIS,
14 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * * See the License for the specific language governing permissions and
16 * * limitations under the License.
18 * * SPDX-License-Identifier: Apache-2.0
19 * * ============LICENSE_END=========================================================
22 package org.openecomp.core.impl;
24 import static org.openecomp.core.converter.datatypes.Constants.DEFINITIONS_DIR;
25 import static org.openecomp.core.converter.datatypes.Constants.GLOBAL_ST_NAME;
26 import static org.openecomp.core.converter.datatypes.Constants.GLOBAL_SUBSTITUTION;
27 import static org.openecomp.core.converter.datatypes.Constants.MAIN_ST_NAME;
28 import static org.openecomp.core.converter.datatypes.Constants.ONAP_INDEX;
29 import static org.openecomp.core.converter.datatypes.Constants.OPENECOMP_HEAT_INDEX;
30 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME;
31 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.HEAT_INDEX_IMPORT_FILE;
32 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.ONAP_INDEX_IMPORT_FILE;
33 import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ORIG_PATH_FILE_NAME;
34 import static org.openecomp.sdc.tosca.csar.ToscaMetadataFileInfo.TOSCA_META_PATH_FILE_NAME;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.HashMap;
40 import java.util.List;
42 import java.util.Objects;
43 import java.util.Optional;
44 import java.util.regex.Pattern;
45 import javax.validation.constraints.NotNull;
46 import org.apache.commons.collections.MapUtils;
47 import org.onap.sdc.tosca.datatypes.model.DataType;
48 import org.onap.sdc.tosca.datatypes.model.Import;
49 import org.onap.sdc.tosca.datatypes.model.NodeType;
50 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
51 import org.openecomp.core.converter.ServiceTemplateReaderService;
52 import org.openecomp.core.converter.ToscaConverter;
53 import org.openecomp.core.converter.datatypes.CsarFileTypes;
54 import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
55 import org.openecomp.core.utilities.file.FileContentHandler;
56 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
57 import org.openecomp.sdc.common.errors.CoreException;
58 import org.openecomp.sdc.common.errors.ErrorCategory;
59 import org.openecomp.sdc.common.errors.ErrorCode;
60 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
61 import org.openecomp.sdc.tosca.services.DataModelUtil;
62 import org.openecomp.sdc.tosca.services.ToscaUtil;
63 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66 import org.yaml.snakeyaml.error.YAMLException;
68 public abstract class AbstractToscaConverter implements ToscaConverter {
70 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractToscaConverter.class);
72 public abstract void convertTopologyTemplate(@NotNull ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService);
74 protected void handleMetadataFile(Map<String, byte[]> csarFiles) {
75 byte[] bytes = csarFiles.remove(TOSCA_META_PATH_FILE_NAME);
77 csarFiles.put(TOSCA_META_ORIG_PATH_FILE_NAME, bytes);
81 protected void handleDefinitionTemplate(String key, Map<String, byte[]> csarFiles, GlobalSubstitutionServiceTemplate gsst) {
83 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
84 Object nodeTypes = readerService.getNodeTypes();
85 if (nodeTypes instanceof Map) {
86 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
87 gsst.appendNodes(nodeTypeMap);
89 gsst.appendDataTypes((Map) readerService.getDataTypes());
90 } catch (YAMLException ye) {
91 throw new CoreException(
92 new ErrorCode.ErrorCodeBuilder().withMessage("Invalid YAML content in file " + key).withCategory(ErrorCategory.APPLICATION).build(),
97 protected String getConcreteArtifactFileName(String fileName) {
98 int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
99 if (artifactIndex < 0) {
102 int artifactDirectoryIndex = artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
103 return fileName.substring(artifactDirectoryIndex);
106 protected void updateToscaServiceModel(ToscaServiceModel toscaServiceModel, Map<String, ServiceTemplate> serviceTemplates,
107 FileContentHandler externalFilesHandler,
108 GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate, Map<String, byte[]> csarFiles,
109 String entryDefinitionServiceTemplateName) {
110 Collection<ServiceTemplate> globalServiceTemplates = GlobalTypesGenerator.getGlobalTypesServiceTemplate(OnboardingTypesEnum.CSAR).values();
111 addGlobalServiceTemplates(globalServiceTemplates, serviceTemplates);
112 toscaServiceModel.setServiceTemplates(serviceTemplates);
113 toscaServiceModel.setEntryDefinitionServiceTemplate(entryDefinitionServiceTemplateName);
114 externalFilesHandler.addFile(TOSCA_META_ORIG_PATH_FILE_NAME, csarFiles.get(TOSCA_META_ORIG_PATH_FILE_NAME));
115 toscaServiceModel.setArtifactFiles(externalFilesHandler);
116 if (MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
117 serviceTemplates.put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
121 private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates, Map<String, ServiceTemplate> serviceTemplates) {
122 for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
123 serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
127 protected void handleServiceTemplate(String serviceTemplateName, String fileName, Map<String, byte[]> csarFiles,
128 Map<String, ServiceTemplate> serviceTemplates) {
129 final byte[] inputServiceTemplate = getServiceTemplateFromCsar(fileName, csarFiles);
130 Optional<ServiceTemplate> serviceTemplate = convertServiceTemplate(fileName, inputServiceTemplate);
131 serviceTemplate.ifPresent(serviceTemplateValue -> addServiceTemplate(serviceTemplateName, serviceTemplateValue, serviceTemplates));
134 private void addServiceTemplate(String serviceTemplateName, ServiceTemplate serviceTemplate, Map<String, ServiceTemplate> serviceTemplates) {
135 serviceTemplates.put(serviceTemplateName, serviceTemplate);
138 private byte[] getServiceTemplateFromCsar(String fileName, Map<String, byte[]> csarFiles) {
139 return csarFiles.get(fileName);
142 private Optional<ServiceTemplate> convertServiceTemplate(String serviceTemplateName, byte[] fileContent) {
143 ServiceTemplate serviceTemplate = new ServiceTemplate();
145 ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(fileContent);
146 convertMetadata(serviceTemplateName, serviceTemplate, readerService);
147 convertToscaVersion(serviceTemplate, readerService);
148 convertImports(serviceTemplate);
149 convertNodeTypes(serviceTemplate, readerService);
150 convertDataTypes(serviceTemplate, readerService);
151 convertTopologyTemplate(serviceTemplate, readerService);
152 } catch (YAMLException ye) {
153 throw new CoreException(new ErrorCode.ErrorCodeBuilder().withMessage("Invalid YAML content in file" + serviceTemplateName)
154 .withCategory(ErrorCategory.APPLICATION).build(), ye);
156 return Optional.of(serviceTemplate);
159 private void convertToscaVersion(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
160 Object toscaVersion = readerService.getToscaVersion();
161 serviceTemplate.setTosca_definitions_version((String) toscaVersion);
164 private void convertImports(ServiceTemplate serviceTemplate) {
165 List<Map<String, Import>> imports = new ArrayList<>();
166 imports.add(createImportMap(OPENECOMP_HEAT_INDEX, HEAT_INDEX_IMPORT_FILE));
167 imports.add(createImportMap(ONAP_INDEX, ONAP_INDEX_IMPORT_FILE));
168 imports.add(createImportMap(GLOBAL_SUBSTITUTION, GLOBAL_ST_NAME));
169 serviceTemplate.setImports(imports);
172 private Map<String, Import> createImportMap(String key, String fileName) {
173 Map<String, Import> importMap = new HashMap<>();
174 Import anImport = new Import();
175 anImport.setFile(fileName);
176 importMap.put(key, anImport);
180 private void convertMetadata(String serviceTemplateName, ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
181 Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
182 Map<String, String> finalMetadata = new HashMap<>();
183 if (MapUtils.isNotEmpty(metadataToConvert)) {
184 for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
185 if (Objects.isNull(metadataEntry.getValue()) || !(metadataEntry.getValue() instanceof String)) {
188 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
191 finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
192 serviceTemplate.setMetadata(finalMetadata);
195 protected void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
196 Map<String, Object> nodeTypes = readerService.getNodeTypes();
197 if (MapUtils.isEmpty(nodeTypes)) {
200 for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
201 Optional<NodeType> nodeType = ToscaConverterUtil.createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(), NodeType.class);
202 nodeType.ifPresent(nodeTypeValue -> DataModelUtil.addNodeType(serviceTemplate, nodeTypeEntry.getKey(), nodeTypeValue));
206 protected void convertDataTypes(final ServiceTemplate serviceTemplate, final ServiceTemplateReaderService readerService) {
208 final Map<String, Object> dataTypes = readerService.getDataTypes();
209 for (final Map.Entry<String, Object> entry : dataTypes.entrySet()) {
210 final Optional<DataType> dataType = ToscaConverterUtil.createObjectFromClass(entry.getKey(), entry.getValue(), DataType.class);
211 dataType.ifPresent(nodeTypeValue -> DataModelUtil.addDataType(serviceTemplate, entry.getKey(), nodeTypeValue));
213 } catch (final Exception ex) {
214 LOGGER.error("Unable to process data types: ", ex);
218 protected CsarFileTypes getFileType(String fileName) {
219 if (isMainServiceTemplate(fileName)) {
220 return CsarFileTypes.mainServiceTemplate;
221 } else if (isGlobalServiceTemplate(fileName)) {
222 return CsarFileTypes.globalServiceTemplate;
223 } else if (isDefinitions(fileName)) {
224 return CsarFileTypes.definitionsFile;
225 } else if (isMetadataFile(fileName)) {
226 return CsarFileTypes.toscaMetadata;
228 return CsarFileTypes.externalFile;
231 protected boolean isMainServiceTemplate(String fileName) {
232 return fileName.endsWith(MAIN_ST_NAME);
235 protected boolean isMetadataFile(String fileName) {
236 return fileName.equals(TOSCA_META_PATH_FILE_NAME);
239 protected boolean isGlobalServiceTemplate(String fileName) {
240 return fileName.endsWith(GLOBAL_ST_NAME);
243 protected boolean isDefinitions(String fileName) {
244 return fileName.startsWith(DEFINITIONS_DIR);
247 private String getTemplateNameFromStName(String serviceTemplateName) {
248 String fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
249 return fileNameWithoutDirectories.split("ServiceTemplate")[0];
252 private String getFileNameWithoutDirectories(String serviceTemplateName) {
253 String fileNameWithoutDirectories;
254 if (serviceTemplateName.contains("/")) {
255 String[] split = serviceTemplateName.split("/");
256 fileNameWithoutDirectories = split[split.length - 1];
257 } else if (serviceTemplateName.contains(File.separator)) {
258 String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
259 fileNameWithoutDirectories = split[split.length - 1];
261 fileNameWithoutDirectories = serviceTemplateName;
263 return fileNameWithoutDirectories;