e1a47db9db215523c9d73c29926aff5d2cf5d594
[sdc.git] / openecomp-be / lib / openecomp-sdc-vendor-software-product-lib / openecomp-sdc-vendor-software-product-core / src / main / java / org / openecomp / sdc / vendorsoftwareproduct / services / impl / filedatastructuremodule / ManifestCreatorNamingConventionImpl.java
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
44   @Override
45   public Optional<ManifestContent> createManifest(
46       VspDetails vspDetails, FilesDataStructure filesDataStructure) {
47     if (Objects.isNull(filesDataStructure)) {
48       return Optional.empty();
49     }
50
51     List<FileData> fileDataList = new ArrayList<>();
52     addModulesToManifestFileDataList(filesDataStructure, fileDataList);
53     addNestedToManifest(filesDataStructure, fileDataList);
54     addArtifactsToManifestFileDataList(filesDataStructure, fileDataList);
55     ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
56     return Optional.of(manifestContent);
57   }
58
59   private void addNestedToManifest(
60       FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
61     if (CollectionUtils.isNotEmpty(filesDataStructure.getNested())) {
62       for (String nested : filesDataStructure.getNested()) {
63         fileDataList.add(createBaseFileData(FileData.Type.HEAT, nested));
64       }
65     }
66   }
67
68   @Override
69   public Optional<ManifestContent> createManifest(VspDetails vspDetails,
70                                                   FileContentHandler fileContentHandler,
71                                                   AnalyzedZipHeatFiles analyzedZipHeatFiles) {
72     logger.info("Trying to generate manifest");
73     if (Objects.isNull(fileContentHandler)
74         || CollectionUtils.isEmpty(fileContentHandler.getFileList())) {
75       logger.info("fileContentHandler or filesList is empty. ManifestContent will not be created");
76       return Optional.empty();
77     }
78
79     Map<String, byte[]> files = fileContentHandler.getFiles();
80
81     List<FileData> fileDataList =
82         createFileDataListFromZipFiles(fileContentHandler, files,
83             analyzedZipHeatFiles.getFilesNotEligbleForModules());
84     ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
85
86     return Optional.of(manifestContent);
87   }
88
89   private ManifestContent createManifest(VspDetails vspDetails, List<FileData> fileDataList) {
90     ManifestContent manifestContent = new ManifestContent();
91     manifestContent.setName(vspDetails.getName());
92     manifestContent.setDescription(vspDetails.getDescription());
93     manifestContent
94         .setVersion(vspDetails.getVersion() == null ? null : vspDetails.getVersion().toString());
95     // vsp version, need to check in confluence
96     manifestContent.setData(fileDataList);
97     return manifestContent;
98   }
99
100   private List<FileData> createFileDataListFromZipFiles(FileContentHandler fileContentHandler,
101                                                         Map<String, byte[]> files,
102                                                         Collection<String> filesNotEligibleForModules) {
103
104     Set<String> processedFiles = new HashSet<>();
105     List<FileData> fileDataList = new ArrayList<>();
106     for (String fileName : files.keySet()) {
107       if (processedFiles.contains(fileName)) {
108         continue;
109       }
110       if (isFileBaseFile(fileName)) {
111         fileDataList
112             .add(createModuleFileData(
113                 fileName, true, processedFiles, fileContentHandler.getFileList(), fileDataList));
114       } else if (isFileModuleFile(fileName, filesNotEligibleForModules)) {
115         fileDataList
116             .add(createModuleFileData(
117                 fileName, false, processedFiles, fileContentHandler.getFileList(), fileDataList));
118       } else {
119         if (HeatFileAnalyzer.isYamlFile(fileName)) {
120           fileDataList.add(createBasicFileData(fileName, FileData.Type.HEAT, null));
121         } else if (HeatFileAnalyzer.isEnvFile(fileName)) {
122           fileDataList.add(createBasicFileData(fileName, FileData.Type.HEAT_ENV, null));
123         } else {
124           fileDataList.add(createBasicFileData(fileName, FileData.Type.OTHER, null));
125         }
126       }
127     }
128     return fileDataList;
129   }
130
131   private boolean isFileModuleFile(String fileName, Collection<String> filesCannotBeModule) {
132     return !filesCannotBeModule.contains(fileName);
133   }
134
135   @Override
136   public boolean isFileBaseFile(String fileName) {
137     return Pattern.matches(Constants.BASE_HEAT_REGEX, fileName) && !isVolFile(fileName);
138   }
139
140   protected boolean isCloudSpecificArtifact(String artifact) {
141       if (artifact.contains(CLOUD_SPECIFIC_FIXED_KEY_WORD)) {
142           for (int i = 0; i < CLOUD_SPECIFIC_KEY_WORDS.length; i++) {
143               if (Arrays.stream(CLOUD_SPECIFIC_KEY_WORDS[i]).noneMatch(str -> artifact.contains(str))) {
144                   return false;
145               }
146           }
147           return true;
148       } else {
149           return false;
150       }
151   }
152
153   private void addArtifactsToManifestFileDataList(
154       FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
155     Collection<String> forArtifacts = CollectionUtils
156         .union(filesDataStructure.getArtifacts(), filesDataStructure.getUnassigned());
157     if (CollectionUtils.isNotEmpty(forArtifacts)) {
158       for (String artifact : forArtifacts) {
159         if (isCloudSpecificArtifact(artifact)) {
160             fileDataList.add(createBaseFileData(FileData.Type.CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT, artifact));
161         } else {
162             fileDataList.add(createBaseFileData(FileData.Type.OTHER, artifact));
163         }
164       }
165     }
166   }
167
168   private void addModulesToManifestFileDataList(
169       FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
170     if (CollectionUtils.isNotEmpty(filesDataStructure.getModules())) {
171       for (Module module : filesDataStructure.getModules()) {
172         FileData fileData = createBaseFileData(FileData.Type.HEAT, module.getYaml());
173         fileData.setBase(module.getIsBase());
174         addEnv(module, fileData);
175         addVolume(module, fileData);
176         fileDataList.add(fileData);
177       }
178     }
179   }
180
181   private void addEnv(Module module, FileData fileData) {
182     if (Objects.nonNull(module.getEnv())) {
183       FileData env = createBaseFileData(FileData.Type.HEAT_ENV, module.getEnv());
184       fileData.addFileData(env);
185     }
186   }
187
188   private void addVolume(Module module, FileData fileData) {
189     String volModule = module.getVol();
190     if (Objects.nonNull(volModule)) {
191       FileData vol = createBaseFileData(FileData.Type.HEAT_VOL, volModule);
192       if (Objects.nonNull(module.getVolEnv())) {
193         vol.addFileData(createBaseFileData(FileData.Type.HEAT_ENV, module.getVolEnv()));
194       }
195       fileData.addFileData(vol);
196     }
197   }
198
199   private FileData createBaseFileData(FileData.Type heat, String yaml) {
200     FileData fileData = new FileData();
201     fileData.setType(heat);
202     fileData.setFile(yaml);
203     return fileData;
204   }
205
206   private FileData createModuleFileData(
207       String moduleFileName, boolean isBase, Set<String> processedFiles,
208       Set<String> fileNames, List<FileData> fileDataList) {
209     FileData moduleFileData = createBasicFileData(moduleFileName, FileData.Type.HEAT, isBase);
210     Optional<String> volFile = fetchRelatedVolume(moduleFileName, fileNames);
211     volFile.ifPresent(vol -> {
212       markFileAsProcessed(vol, processedFiles);
213       removeFromFileDataListIfAlreadyProcessed(fileDataList, vol);
214       FileData volFileData = createBasicFileData(vol, FileData.Type.HEAT_VOL, null);
215       Optional<String> envFile = fetchRelatedEnv(vol, fileNames);
216       envFile.ifPresent(env -> {
217         markFileAsProcessed(env, processedFiles);
218         removeFromFileDataListIfAlreadyProcessed(fileDataList, env);
219         FileData envFileData = createBasicFileData(env, FileData.Type.HEAT_ENV, null);
220         volFileData.addFileData(envFileData);
221       });
222       moduleFileData.addFileData(volFileData);
223     });
224     Optional<String> envFile = fetchRelatedEnv(moduleFileName, fileNames);
225     envFile.ifPresent(env -> {
226       markFileAsProcessed(env, processedFiles);
227       FileData envFileData = createBasicFileData(env, FileData.Type.HEAT_ENV, null);
228       moduleFileData.addFileData(envFileData);
229     });
230     return moduleFileData;
231   }
232
233   private void removeFromFileDataListIfAlreadyProcessed(List<FileData> fileDataList, String vol) {
234     fileDataList.removeIf(fileData -> fileData.getFile().equals(vol));
235   }
236
237   private FileData createBasicFileData(String fileName, FileData.Type type, Boolean isBase) {
238     FileData fileData = new FileData();
239     if (isBase != null) {
240       fileData.setBase(isBase);
241     }
242     fileData.setType(type);
243     fileData.setFile(fileName);
244     return fileData;
245   }
246
247   private Optional<String> fetchRelatedEnv(String fileName, Set<String> fileNames) {
248     String envFileName
249         = fileName.substring(0, fileName.lastIndexOf(".")) + Constants.ENV_FILE_EXTENSION;
250     return fileNames.contains(envFileName) ? Optional.of(envFileName) : Optional.empty();
251   }
252
253   private Optional<String> fetchRelatedVolume(String fileName, Set<String> fileNames) {
254
255     String volFile1stExt =
256         extractVolFileName(fileName, ".yaml");
257     String volFile2ndExt =
258         extractVolFileName(fileName, ".yml");
259
260     if (fileNames.contains(volFile1stExt)) {
261       return Optional.of(volFile1stExt);
262     }
263     if (fileNames.contains(volFile2ndExt)) {
264       return Optional.of(volFile2ndExt);
265     }
266     return Optional.empty();
267   }
268
269   private String extractVolFileName(String fileName, String fileExt) {
270     return fileName.substring(
271         0, fileName.lastIndexOf("."))
272         + Constants.VOL_FILE_NAME_SUFFIX + fileExt;
273   }
274
275
276   private boolean isVolFile(String fileName) {
277     return fileName
278         .endsWith(
279             Constants.VOL_FILE_NAME_SUFFIX + ".yaml")
280         || fileName.endsWith(Constants.VOL_FILE_NAME_SUFFIX + ".yml");
281   }
282
283
284   private void markFileAsProcessed(String fileName, Set<String> processedFiles) {
285     processedFiles.add(fileName);
286   }
287 }