3f061b059ce3b149659183e8f94939231c1760b5
[sdc.git] /
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.vendorsoftwareproduct.services.impl.filedatastructuremodule;
18
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.openecomp.core.utilities.file.FileContentHandler;
21 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
22 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
23 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
24 import org.openecomp.sdc.vendorsoftwareproduct.services.HeatFileAnalyzer;
25 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.ManifestCreator;
26 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.AnalyzedZipHeatFiles;
27 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.Constants;
28 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
29 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.Module;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import java.util.*;
34 import java.util.regex.Pattern;
35
36 public class ManifestCreatorNamingConventionImpl implements ManifestCreator {
37   protected static final Logger logger =
38       LoggerFactory.getLogger(ManifestCreatorNamingConventionImpl.class);
39
40   private static final String CLOUD_SPECIFIC_FIXED_KEY_WORD = "cloudtech";
41   private static final String[][] CLOUD_SPECIFIC_KEY_WORDS = {{"k8s", "azure", "aws"}, /* cloud specific technology */
42                                                               {"charts", "day0", "configtemplate"} /*cloud specific sub type*/};
43   private static final String CONTROLLER_BLUEPRINT_ARCHIVE_FIXED_KEY_WORD = "CBA";
44   private static final String HELM_KEY_WORD = "HELM";
45
46   @Override
47   public Optional<ManifestContent> createManifest(
48       VspDetails vspDetails, FilesDataStructure filesDataStructure) {
49     if (Objects.isNull(filesDataStructure)) {
50       return Optional.empty();
51     }
52
53     List<FileData> fileDataList = new ArrayList<>();
54     addModulesToManifestFileDataList(filesDataStructure, fileDataList);
55     addNestedToManifest(filesDataStructure, fileDataList);
56     addArtifactsToManifestFileDataList(filesDataStructure, fileDataList);
57     ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
58     return Optional.of(manifestContent);
59   }
60
61   private void addNestedToManifest(
62       FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
63     if (CollectionUtils.isNotEmpty(filesDataStructure.getNested())) {
64       for (String nested : filesDataStructure.getNested()) {
65         fileDataList.add(createBaseFileData(FileData.Type.HEAT, nested));
66       }
67     }
68   }
69
70   @Override
71   public Optional<ManifestContent> createManifest(VspDetails vspDetails,
72                                                   FileContentHandler fileContentHandler,
73                                                   AnalyzedZipHeatFiles analyzedZipHeatFiles) {
74     logger.info("Trying to generate manifest");
75     if (Objects.isNull(fileContentHandler)
76         || CollectionUtils.isEmpty(fileContentHandler.getFileList())) {
77       logger.info("fileContentHandler or filesList is empty. ManifestContent will not be created");
78       return Optional.empty();
79     }
80
81     Map<String, byte[]> files = fileContentHandler.getFiles();
82
83     List<FileData> fileDataList =
84         createFileDataListFromZipFiles(fileContentHandler, files,
85             analyzedZipHeatFiles.getFilesNotEligbleForModules());
86     ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
87
88     return Optional.of(manifestContent);
89   }
90
91   private ManifestContent createManifest(VspDetails vspDetails, List<FileData> fileDataList) {
92     ManifestContent manifestContent = new ManifestContent();
93     manifestContent.setName(vspDetails.getName());
94     manifestContent.setDescription(vspDetails.getDescription());
95     manifestContent
96         .setVersion(vspDetails.getVersion() == null ? null : vspDetails.getVersion().toString());
97     // vsp version, need to check in confluence
98     manifestContent.setData(fileDataList);
99     return manifestContent;
100   }
101
102   private List<FileData> createFileDataListFromZipFiles(FileContentHandler fileContentHandler,
103                                                         Map<String, byte[]> files,
104                                                         Collection<String> filesNotEligibleForModules) {
105
106     Set<String> processedFiles = new HashSet<>();
107     List<FileData> fileDataList = new ArrayList<>();
108     for (String fileName : files.keySet()) {
109       if (processedFiles.contains(fileName)) {
110         continue;
111       }
112       if (isFileBaseFile(fileName)) {
113         fileDataList
114             .add(createModuleFileData(
115                 fileName, true, processedFiles, fileContentHandler.getFileList(), fileDataList));
116       } else if (isFileModuleFile(fileName, filesNotEligibleForModules)) {
117         fileDataList
118             .add(createModuleFileData(
119                 fileName, false, processedFiles, fileContentHandler.getFileList(), fileDataList));
120       } else {
121         if (HeatFileAnalyzer.isYamlFile(fileName)) {
122           fileDataList.add(createBasicFileData(fileName, FileData.Type.HEAT, null));
123         } else if (HeatFileAnalyzer.isEnvFile(fileName)) {
124           fileDataList.add(createBasicFileData(fileName, FileData.Type.HEAT_ENV, null));
125         } else {
126           fileDataList.add(createBasicFileData(fileName, FileData.Type.OTHER, null));
127         }
128       }
129     }
130     return fileDataList;
131   }
132
133   private boolean isFileModuleFile(String fileName, Collection<String> filesCannotBeModule) {
134     return !filesCannotBeModule.contains(fileName);
135   }
136
137   @Override
138   public boolean isFileBaseFile(String fileName) {
139     return Pattern.matches(Constants.BASE_HEAT_REGEX, fileName) && !isVolFile(fileName);
140   }
141
142   protected boolean isCloudSpecificArtifact(String artifact) {
143       if (artifact.contains(CLOUD_SPECIFIC_FIXED_KEY_WORD)) {
144           for (int i = 0; i < CLOUD_SPECIFIC_KEY_WORDS.length; i++) {
145               if (Arrays.stream(CLOUD_SPECIFIC_KEY_WORDS[i]).noneMatch(str -> artifact.contains(str))) {
146                   return false;
147               }
148           }
149           return true;
150       } else {
151           return false;
152       }
153   }
154
155   private boolean isControllerBlueprintArchive(String artifact) {
156     return artifact.toUpperCase().contains(CONTROLLER_BLUEPRINT_ARCHIVE_FIXED_KEY_WORD);
157   }
158
159   private boolean isHelm(String artifact) {
160     return artifact.toUpperCase().contains(HELM_KEY_WORD);
161   }
162
163   private void addArtifactsToManifestFileDataList(
164       FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
165     Collection<String> forArtifacts = CollectionUtils
166         .union(filesDataStructure.getArtifacts(), filesDataStructure.getUnassigned());
167     if (CollectionUtils.isNotEmpty(forArtifacts)) {
168       for (String artifact : forArtifacts) {
169         if (isCloudSpecificArtifact(artifact)) {
170             fileDataList.add(createBaseFileData(FileData.Type.CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT, artifact));
171         } else if (isControllerBlueprintArchive(artifact)) {
172           fileDataList.add(createBaseFileData(FileData.Type.CONTROLLER_BLUEPRINT_ARCHIVE, artifact));
173         } else if (isHelm(artifact)) {
174           fileDataList.add(createBaseFileData(FileData.Type.HELM, artifact));
175         }
176         else {
177           fileDataList.add(createBaseFileData(FileData.Type.OTHER, artifact));
178         }
179       }
180     }
181   }
182
183   private void addModulesToManifestFileDataList(
184       FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
185     if (CollectionUtils.isNotEmpty(filesDataStructure.getModules())) {
186       for (Module module : filesDataStructure.getModules()) {
187         FileData.Type type = module.getType();
188         if (type == null) {
189           type = FileData.Type.HEAT;
190         }
191         FileData fileData = createBaseFileData(type, module.getYaml());
192         fileData.setBase(module.getIsBase());
193         addEnv(module, fileData);
194         addVolume(module, fileData);
195         fileDataList.add(fileData);
196       }
197     }
198   }
199
200   private void addEnv(Module module, FileData fileData) {
201     if (Objects.nonNull(module.getEnv())) {
202       FileData env = createBaseFileData(FileData.Type.HEAT_ENV, module.getEnv());
203       fileData.addFileData(env);
204     }
205   }
206
207   private void addVolume(Module module, FileData fileData) {
208     String volModule = module.getVol();
209     if (Objects.nonNull(volModule)) {
210       FileData vol = createBaseFileData(FileData.Type.HEAT_VOL, volModule);
211       if (Objects.nonNull(module.getVolEnv())) {
212         vol.addFileData(createBaseFileData(FileData.Type.HEAT_ENV, module.getVolEnv()));
213       }
214       fileData.addFileData(vol);
215     }
216   }
217
218   private FileData createBaseFileData(FileData.Type heat, String yaml) {
219     FileData fileData = new FileData();
220     fileData.setType(heat);
221     fileData.setFile(yaml);
222     return fileData;
223   }
224
225   private FileData createModuleFileData(
226       String moduleFileName, boolean isBase, Set<String> processedFiles,
227       Set<String> fileNames, List<FileData> fileDataList) {
228     FileData moduleFileData = createBasicFileData(moduleFileName, FileData.Type.HEAT, isBase);
229     Optional<String> volFile = fetchRelatedVolume(moduleFileName, fileNames);
230     volFile.ifPresent(vol -> {
231       markFileAsProcessed(vol, processedFiles);
232       removeFromFileDataListIfAlreadyProcessed(fileDataList, vol);
233       FileData volFileData = createBasicFileData(vol, FileData.Type.HEAT_VOL, null);
234       Optional<String> envFile = fetchRelatedEnv(vol, fileNames);
235       envFile.ifPresent(env -> {
236         markFileAsProcessed(env, processedFiles);
237         removeFromFileDataListIfAlreadyProcessed(fileDataList, env);
238         FileData envFileData = createBasicFileData(env, FileData.Type.HEAT_ENV, null);
239         volFileData.addFileData(envFileData);
240       });
241       moduleFileData.addFileData(volFileData);
242     });
243     Optional<String> envFile = fetchRelatedEnv(moduleFileName, fileNames);
244     envFile.ifPresent(env -> {
245       markFileAsProcessed(env, processedFiles);
246       FileData envFileData = createBasicFileData(env, FileData.Type.HEAT_ENV, null);
247       moduleFileData.addFileData(envFileData);
248     });
249     return moduleFileData;
250   }
251
252   private void removeFromFileDataListIfAlreadyProcessed(List<FileData> fileDataList, String vol) {
253     fileDataList.removeIf(fileData -> fileData.getFile().equals(vol));
254   }
255
256   private FileData createBasicFileData(String fileName, FileData.Type type, Boolean isBase) {
257     FileData fileData = new FileData();
258     if (isBase != null) {
259       fileData.setBase(isBase);
260     }
261     fileData.setType(type);
262     fileData.setFile(fileName);
263     return fileData;
264   }
265
266   private Optional<String> fetchRelatedEnv(String fileName, Set<String> fileNames) {
267     String envFileName
268         = fileName.substring(0, fileName.lastIndexOf(".")) + Constants.ENV_FILE_EXTENSION;
269     return fileNames.contains(envFileName) ? Optional.of(envFileName) : Optional.empty();
270   }
271
272   private Optional<String> fetchRelatedVolume(String fileName, Set<String> fileNames) {
273
274     String volFile1stExt =
275         extractVolFileName(fileName, ".yaml");
276     String volFile2ndExt =
277         extractVolFileName(fileName, ".yml");
278
279     if (fileNames.contains(volFile1stExt)) {
280       return Optional.of(volFile1stExt);
281     }
282     if (fileNames.contains(volFile2ndExt)) {
283       return Optional.of(volFile2ndExt);
284     }
285     return Optional.empty();
286   }
287
288   private String extractVolFileName(String fileName, String fileExt) {
289     return fileName.substring(
290         0, fileName.lastIndexOf("."))
291         + Constants.VOL_FILE_NAME_SUFFIX + fileExt;
292   }
293
294
295   private boolean isVolFile(String fileName) {
296     return fileName
297         .endsWith(
298             Constants.VOL_FILE_NAME_SUFFIX + ".yaml")
299         || fileName.endsWith(Constants.VOL_FILE_NAME_SUFFIX + ".yml");
300   }
301
302
303   private void markFileAsProcessed(String fileName, Set<String> processedFiles) {
304     processedFiles.add(fileName);
305   }
306 }