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