6619a4c580c65e5d33f2c338f99a66b63b727eab
[sdc.git] /
1 /*
2  * -
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
9  *  *
10  *  *      http://www.apache.org/licenses/LICENSE-2.0
11  *  *
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.
17  *  *
18  *  * SPDX-License-Identifier: Apache-2.0
19  *  * ============LICENSE_END=========================================================
20  *
21  */
22
23 package org.openecomp.core.impl;
24
25 import static org.openecomp.core.converter.datatypes.Constants.ONAP_INDEX;
26 import static org.openecomp.core.converter.datatypes.Constants.definitionsDir;
27 import static org.openecomp.core.converter.datatypes.Constants.globalStName;
28 import static org.openecomp.core.converter.datatypes.Constants.globalSubstitution;
29 import static org.openecomp.core.converter.datatypes.Constants.mainStName;
30 import static org.openecomp.core.converter.datatypes.Constants.openecompHeatIndex;
31 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME;
32 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.HEAT_INDEX_IMPORT_FILE;
33 import static org.openecomp.core.impl.GlobalSubstitutionServiceTemplate.ONAP_INDEX_IMPORT_FILE;
34 import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ORIG_PATH_FILE_NAME;
35 import static org.openecomp.sdc.tosca.csar.ToscaMetadataFileInfo.TOSCA_META_PATH_FILE_NAME;
36
37 import java.io.File;
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Objects;
44 import java.util.Optional;
45 import java.util.regex.Pattern;
46 import org.apache.commons.collections.MapUtils;
47 import org.onap.sdc.tosca.datatypes.model.Import;
48 import org.onap.sdc.tosca.datatypes.model.NodeType;
49 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
50 import org.openecomp.core.converter.ServiceTemplateReaderService;
51 import org.openecomp.core.converter.ToscaConverter;
52 import org.openecomp.core.converter.datatypes.CsarFileTypes;
53 import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
54 import org.openecomp.core.utilities.file.FileContentHandler;
55 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
56 import org.openecomp.sdc.common.errors.CoreException;
57 import org.openecomp.sdc.common.errors.ErrorCategory;
58 import org.openecomp.sdc.common.errors.ErrorCode;
59 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
60 import org.openecomp.sdc.tosca.services.DataModelUtil;
61 import org.openecomp.sdc.tosca.services.ToscaUtil;
62 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
63 import org.yaml.snakeyaml.error.YAMLException;
64
65 public abstract class AbstractToscaConverter implements ToscaConverter {
66
67     public abstract void convertTopologyTemplate(ServiceTemplate serviceTemplate,
68                                                  ServiceTemplateReaderService readerService);
69
70     protected void handleMetadataFile(Map<String, byte[]> csarFiles) {
71         byte[] bytes = csarFiles.remove(TOSCA_META_PATH_FILE_NAME);
72         if (bytes != null) {
73             csarFiles.put(TOSCA_META_ORIG_PATH_FILE_NAME, bytes);
74         }
75     }
76
77     protected void handleDefintionTemplate(String key, Map<String, byte[]> csarFiles,
78                                            GlobalSubstitutionServiceTemplate gsst) {
79         try {
80             ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(csarFiles.get(key));
81             Object nodeTypes = readerService.getNodeTypes();
82             if (nodeTypes instanceof Map) {
83                 Map<String, NodeType> nodeTypeMap = (Map<String, NodeType>) nodeTypes;
84                 gsst.appendNodes(nodeTypeMap);
85             }
86         } catch (YAMLException ye) {
87             throw new CoreException(new ErrorCode.ErrorCodeBuilder()
88                     .withMessage("Invalid YAML content in file " + key)
89                     .withCategory(ErrorCategory.APPLICATION).build(), ye);
90         }
91     }
92
93     protected String getConcreteArtifactFileName(String fileName) {
94         int artifactIndex = fileName.indexOf(CsarFileTypes.Artifacts.name());
95         if (artifactIndex < 0) {
96             return fileName;
97         }
98
99         int artifactDirectoryIndex =
100                 artifactIndex + CsarFileTypes.Artifacts.name().length() + 1;
101         return fileName.substring(artifactDirectoryIndex);
102     }
103
104     protected void updateToscaServiceModel(ToscaServiceModel toscaServiceModel,
105                                            Map<String, ServiceTemplate> serviceTemplates,
106                                            FileContentHandler externalFilesHandler,
107                                            GlobalSubstitutionServiceTemplate globalSubstitutionServiceTemplate,
108                                            Map<String, byte[]> csarFiles, String entryDefinitionServiceTemplateName) {
109         Collection<ServiceTemplate> globalServiceTemplates =
110                 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,
115                 csarFiles.get(TOSCA_META_ORIG_PATH_FILE_NAME));
116         toscaServiceModel.setArtifactFiles(externalFilesHandler);
117
118         if (MapUtils.isNotEmpty(globalSubstitutionServiceTemplate.getNode_types())) {
119             serviceTemplates
120                     .put(GLOBAL_SUBSTITUTION_SERVICE_FILE_NAME, globalSubstitutionServiceTemplate);
121         }
122     }
123
124     private void addGlobalServiceTemplates(Collection<ServiceTemplate> globalServiceTemplates,
125                                            Map<String, ServiceTemplate> serviceTemplates) {
126         for (ServiceTemplate serviceTemplate : globalServiceTemplates) {
127             serviceTemplates.put(ToscaUtil.getServiceTemplateFileName(serviceTemplate), serviceTemplate);
128         }
129     }
130
131     protected void handleServiceTemplate(String serviceTemplateName,
132                                          String fileName, Map<String, byte[]> csarFiles,
133                                          Map<String, ServiceTemplate> serviceTemplates) {
134         final byte[] inputServiceTemplate = getServiceTemplateFromCsar(fileName, csarFiles);
135         Optional<ServiceTemplate> serviceTemplate = convertServiceTemplate(fileName, inputServiceTemplate);
136         serviceTemplate.ifPresent(
137                 serviceTemplateValue -> addServiceTemplate(serviceTemplateName, serviceTemplateValue,
138                         serviceTemplates));
139     }
140
141     private void addServiceTemplate(String serviceTemplateName,
142                                     ServiceTemplate serviceTemplate,
143                                     Map<String, ServiceTemplate> serviceTemplates) {
144         serviceTemplates.put(serviceTemplateName, serviceTemplate);
145     }
146
147     private byte[] getServiceTemplateFromCsar(String fileName, Map<String, byte[]> csarFiles) {
148         return csarFiles.get(fileName);
149     }
150
151     private Optional<ServiceTemplate> convertServiceTemplate(String serviceTemplateName,
152                                                              byte[] fileContent) {
153         ServiceTemplate serviceTemplate = new ServiceTemplate();
154         try {
155             ServiceTemplateReaderService readerService =
156                     new ServiceTemplateReaderServiceImpl(fileContent);
157             convertMetadata(serviceTemplateName, serviceTemplate, readerService);
158             convertToscaVersion(serviceTemplate, readerService);
159             convertImports(serviceTemplate);
160             convertNodeTypes(serviceTemplate, readerService);
161             convertTopologyTemplate(serviceTemplate, readerService);
162         } catch (YAMLException ye) {
163             throw new CoreException(new ErrorCode.ErrorCodeBuilder()
164                     .withMessage("Invalid YAML content in file" + serviceTemplateName)
165                     .withCategory(ErrorCategory.APPLICATION).build(), ye);
166         }
167
168
169         return Optional.of(serviceTemplate);
170     }
171
172     private void convertToscaVersion(ServiceTemplate serviceTemplate,
173                                      ServiceTemplateReaderService readerService) {
174         Object toscaVersion = readerService.getToscaVersion();
175         serviceTemplate.setTosca_definitions_version((String) toscaVersion);
176     }
177
178     private void convertImports(ServiceTemplate serviceTemplate) {
179         List<Map<String, Import>> imports = new ArrayList<>();
180         imports.add(createImportMap(openecompHeatIndex, HEAT_INDEX_IMPORT_FILE));
181         imports.add(createImportMap(ONAP_INDEX, ONAP_INDEX_IMPORT_FILE));
182         imports.add(createImportMap(globalSubstitution, globalStName));
183         serviceTemplate.setImports(imports);
184     }
185
186     private Map<String, Import> createImportMap(String key, String fileName) {
187         Map<String, Import> importMap = new HashMap<>();
188         Import anImport = new Import();
189         anImport.setFile(fileName);
190         importMap.put(key, anImport);
191
192         return importMap;
193     }
194
195     private void convertMetadata(String serviceTemplateName,
196                                  ServiceTemplate serviceTemplate,
197                                  ServiceTemplateReaderService readerService) {
198         Map<String, Object> metadataToConvert = (Map<String, Object>) readerService.getMetadata();
199         Map<String, String> finalMetadata = new HashMap<>();
200
201         if (MapUtils.isNotEmpty(metadataToConvert)) {
202             for (Map.Entry<String, Object> metadataEntry : metadataToConvert.entrySet()) {
203                 if (Objects.isNull(metadataEntry.getValue()) ||
204                         !(metadataEntry.getValue() instanceof String)) {
205                     continue;
206                 }
207                 finalMetadata.put(metadataEntry.getKey(), (String) metadataEntry.getValue());
208             }
209         }
210
211         finalMetadata.put("template_name", getTemplateNameFromStName(serviceTemplateName));
212         serviceTemplate.setMetadata(finalMetadata);
213     }
214
215     protected void convertNodeTypes(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
216         Map<String, Object> nodeTypes = readerService.getNodeTypes();
217         if (MapUtils.isEmpty(nodeTypes)) {
218             return;
219         }
220
221         for (Map.Entry<String, Object> nodeTypeEntry : nodeTypes.entrySet()) {
222             Optional<NodeType> nodeType = ToscaConverterUtil
223                     .createObjectFromClass(nodeTypeEntry.getKey(), nodeTypeEntry.getValue(),
224                             NodeType.class);
225
226             nodeType.ifPresent(nodeTypeValue -> DataModelUtil
227                     .addNodeType(serviceTemplate, nodeTypeEntry.getKey(), nodeTypeValue));
228         }
229     }
230
231     protected CsarFileTypes getFileType(String fileName) {
232         if (isMainServiceTemplate(fileName)) {
233             return CsarFileTypes.mainServiceTemplate;
234         } else if (isGlobalServiceTemplate(fileName)) {
235             return CsarFileTypes.globalServiceTemplate;
236         } else if (isDefinitions(fileName)) {
237             return CsarFileTypes.definitionsFile;
238         } else if (isMetadataFile(fileName)) {
239             return CsarFileTypes.toscaMetadata;
240         }
241         return CsarFileTypes.externalFile;
242     }
243
244     protected boolean isMainServiceTemplate(String fileName) {
245         return fileName.endsWith(mainStName);
246     }
247
248     protected boolean isMetadataFile(String fileName) {
249         return fileName.equals(TOSCA_META_PATH_FILE_NAME);
250     }
251
252     protected boolean isGlobalServiceTemplate(String fileName) {
253         return fileName.endsWith(globalStName);
254     }
255
256     protected boolean isDefinitions(String fileName) {
257         return fileName.startsWith(definitionsDir);
258     }
259
260     private String getTemplateNameFromStName(String serviceTemplateName) {
261         String fileNameWithoutDirectories = getFileNameWithoutDirectories(serviceTemplateName);
262         return fileNameWithoutDirectories.split("ServiceTemplate")[0];
263     }
264
265     private String getFileNameWithoutDirectories(String serviceTemplateName) {
266         String fileNameWithoutDirectories;
267         if (serviceTemplateName.contains("/")) {
268             String[] split = serviceTemplateName.split("/");
269             fileNameWithoutDirectories = split[split.length - 1];
270         } else if (serviceTemplateName.contains(File.separator)) {
271             String[] split = serviceTemplateName.split(Pattern.quote(File.separator));
272             fileNameWithoutDirectories = split[split.length - 1];
273         } else {
274             fileNameWithoutDirectories = serviceTemplateName;
275         }
276         return fileNameWithoutDirectories;
277     }
278 }