2 * Copyright © 2016-2017 European Support Limited
3 * Modifications copyright (c) 2021 Nokia
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.openecomp.sdc.vendorsoftwareproduct.services.impl.filedatastructuremodule;
20 import org.apache.commons.collections4.CollectionUtils;
21 import org.openecomp.core.utilities.file.FileContentHandler;
22 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
23 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
24 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
25 import org.openecomp.sdc.vendorsoftwareproduct.services.HeatFileAnalyzer;
26 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.ManifestCreator;
27 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.AnalyzedZipHeatFiles;
28 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.Constants;
29 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
30 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.Module;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 import java.util.regex.Pattern;
37 public class ManifestCreatorNamingConventionImpl implements ManifestCreator {
38 protected static final Logger logger =
39 LoggerFactory.getLogger(ManifestCreatorNamingConventionImpl.class);
41 private static final String CLOUD_SPECIFIC_FIXED_KEY_WORD = "cloudtech";
42 private static final String[][] CLOUD_SPECIFIC_KEY_WORDS = {{"k8s", "azure", "aws"}, /* cloud specific technology */
43 {"charts", "day0", "configtemplate"} /*cloud specific sub type*/};
44 private static final String CONTROLLER_BLUEPRINT_ARCHIVE_FIXED_KEY_WORD = "CBA";
45 private static final String HELM_KEY_WORD = "HELM";
48 public Optional<ManifestContent> createManifest(
49 VspDetails vspDetails, FilesDataStructure filesDataStructure) {
50 if (Objects.isNull(filesDataStructure)) {
51 return Optional.empty();
54 List<FileData> fileDataList = new ArrayList<>();
55 addModulesToManifestFileDataList(filesDataStructure, fileDataList);
56 addNestedToManifest(filesDataStructure, fileDataList);
57 addArtifactsToManifestFileDataList(filesDataStructure, fileDataList);
59 ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
60 return Optional.of(manifestContent);
64 public Optional<ManifestContent> createManifestFromExisting(VspDetails vspDetails, FilesDataStructure filesDataStructure, ManifestContent existingManifest) {
65 if (Objects.isNull(filesDataStructure)) {
66 return Optional.empty();
69 List<FileData> fileDataList = new ArrayList<>();
70 addModulesToManifestFileDataList(filesDataStructure, fileDataList);
71 addNestedToManifest(filesDataStructure, fileDataList);
72 addArtifactsToManifestFileDataList(filesDataStructure, fileDataList, existingManifest);
74 ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
75 return Optional.of(manifestContent);
78 private void addArtifactsToManifestFileDataList(FilesDataStructure filesDataStructure, List<FileData> fileDataList, ManifestContent existingManifest) {
79 Collection<String> forArtifacts = CollectionUtils
80 .union(filesDataStructure.getArtifacts(), filesDataStructure.getUnassigned());
81 if (CollectionUtils.isNotEmpty(forArtifacts)) {
82 for (String artifact : forArtifacts) {
83 if (isCloudSpecificArtifact(artifact)) {
84 fileDataList.add(createBaseFileData(FileData.Type.CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT, artifact));
85 } else if (isControllerBlueprintArchive(artifact)) {
86 fileDataList.add(createBaseFileData(FileData.Type.CONTROLLER_BLUEPRINT_ARCHIVE, artifact));
87 } else if (isHelm(artifact)) {
88 fileDataList.add(createBaseFileData(FileData.Type.HELM, artifact));
89 } else if (isPmDictionary(artifact, existingManifest)) {
90 fileDataList.add(createBaseFileData(FileData.Type.PM_DICTIONARY, artifact));
93 fileDataList.add(createBaseFileData(FileData.Type.OTHER, artifact));
99 private boolean isPmDictionary(String artifact, ManifestContent existingManifest) {
100 return existingManifest.getData()
102 .filter(fileData -> fileData.getType()
103 .equals(FileData.Type.PM_DICTIONARY))
104 .map(FileData::getFile)
105 .anyMatch(pmDictionaryFile -> pmDictionaryFile.equals(artifact));
108 private void addNestedToManifest(
109 FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
110 if (CollectionUtils.isNotEmpty(filesDataStructure.getNested())) {
111 for (String nested : filesDataStructure.getNested()) {
112 fileDataList.add(createBaseFileData(FileData.Type.HEAT, nested));
118 public Optional<ManifestContent> createManifest(VspDetails vspDetails,
119 FileContentHandler fileContentHandler,
120 AnalyzedZipHeatFiles analyzedZipHeatFiles) {
121 logger.info("Trying to generate manifest");
122 if (Objects.isNull(fileContentHandler)
123 || CollectionUtils.isEmpty(fileContentHandler.getFileList())) {
124 logger.info("fileContentHandler or filesList is empty. ManifestContent will not be created");
125 return Optional.empty();
128 Map<String, byte[]> files = fileContentHandler.getFiles();
130 List<FileData> fileDataList =
131 createFileDataListFromZipFiles(fileContentHandler, files,
132 analyzedZipHeatFiles.getFilesNotEligbleForModules());
133 ManifestContent manifestContent = createManifest(vspDetails, fileDataList);
135 return Optional.of(manifestContent);
138 private ManifestContent createManifest(VspDetails vspDetails, List<FileData> fileDataList) {
139 ManifestContent manifestContent = new ManifestContent();
140 manifestContent.setName(vspDetails.getName());
141 manifestContent.setDescription(vspDetails.getDescription());
143 .setVersion(vspDetails.getVersion() == null ? null : vspDetails.getVersion().toString());
144 // vsp version, need to check in confluence
145 manifestContent.setData(fileDataList);
146 return manifestContent;
149 private List<FileData> createFileDataListFromZipFiles(FileContentHandler fileContentHandler,
150 Map<String, byte[]> files,
151 Collection<String> filesNotEligibleForModules) {
153 Set<String> processedFiles = new HashSet<>();
154 List<FileData> fileDataList = new ArrayList<>();
155 for (String fileName : files.keySet()) {
156 if (processedFiles.contains(fileName)) {
159 if (isFileBaseFile(fileName)) {
161 .add(createModuleFileData(
162 fileName, true, processedFiles, fileContentHandler.getFileList(), fileDataList));
163 } else if (isFileModuleFile(fileName, filesNotEligibleForModules)) {
165 .add(createModuleFileData(
166 fileName, false, processedFiles, fileContentHandler.getFileList(), fileDataList));
168 if (HeatFileAnalyzer.isYamlFile(fileName)) {
169 fileDataList.add(createBasicFileData(fileName, FileData.Type.HEAT, null));
170 } else if (HeatFileAnalyzer.isEnvFile(fileName)) {
171 fileDataList.add(createBasicFileData(fileName, FileData.Type.HEAT_ENV, null));
173 fileDataList.add(createBasicFileData(fileName, FileData.Type.OTHER, null));
180 private boolean isFileModuleFile(String fileName, Collection<String> filesCannotBeModule) {
181 return !filesCannotBeModule.contains(fileName);
185 public boolean isFileBaseFile(String fileName) {
186 return Pattern.matches(Constants.BASE_HEAT_REGEX, fileName) && !isVolFile(fileName);
189 protected boolean isCloudSpecificArtifact(String artifact) {
190 if (artifact.contains(CLOUD_SPECIFIC_FIXED_KEY_WORD)) {
191 for (int i = 0; i < CLOUD_SPECIFIC_KEY_WORDS.length; i++) {
192 if (Arrays.stream(CLOUD_SPECIFIC_KEY_WORDS[i]).noneMatch(str -> artifact.contains(str))) {
202 private boolean isControllerBlueprintArchive(String artifact) {
203 return artifact.toUpperCase().contains(CONTROLLER_BLUEPRINT_ARCHIVE_FIXED_KEY_WORD);
206 private boolean isHelm(String artifact) {
207 return artifact.toUpperCase().contains(HELM_KEY_WORD);
210 private void addArtifactsToManifestFileDataList(
211 FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
212 Collection<String> forArtifacts = CollectionUtils
213 .union(filesDataStructure.getArtifacts(), filesDataStructure.getUnassigned());
214 if (CollectionUtils.isNotEmpty(forArtifacts)) {
215 for (String artifact : forArtifacts) {
216 if (isCloudSpecificArtifact(artifact)) {
217 fileDataList.add(createBaseFileData(FileData.Type.CLOUD_TECHNOLOGY_SPECIFIC_ARTIFACT, artifact));
218 } else if (isControllerBlueprintArchive(artifact)) {
219 fileDataList.add(createBaseFileData(FileData.Type.CONTROLLER_BLUEPRINT_ARCHIVE, artifact));
220 } else if (isHelm(artifact)) {
221 fileDataList.add(createBaseFileData(FileData.Type.HELM, artifact));
223 fileDataList.add(createBaseFileData(FileData.Type.OTHER, artifact));
229 private void addModulesToManifestFileDataList(
230 FilesDataStructure filesDataStructure, List<FileData> fileDataList) {
231 if (CollectionUtils.isNotEmpty(filesDataStructure.getModules())) {
232 for (Module module : filesDataStructure.getModules()) {
233 FileData.Type type = module.getType();
235 type = FileData.Type.HEAT;
237 FileData fileData = createBaseFileData(type, module.getYaml());
238 fileData.setBase(module.getIsBase());
239 addEnv(module, fileData);
240 addVolume(module, fileData);
241 fileDataList.add(fileData);
246 private void addEnv(Module module, FileData fileData) {
247 if (Objects.nonNull(module.getEnv())) {
248 FileData env = createBaseFileData(FileData.Type.HEAT_ENV, module.getEnv());
249 fileData.addFileData(env);
253 private void addVolume(Module module, FileData fileData) {
254 String volModule = module.getVol();
255 if (Objects.nonNull(volModule)) {
256 FileData vol = createBaseFileData(FileData.Type.HEAT_VOL, volModule);
257 if (Objects.nonNull(module.getVolEnv())) {
258 vol.addFileData(createBaseFileData(FileData.Type.HEAT_ENV, module.getVolEnv()));
260 fileData.addFileData(vol);
264 private FileData createBaseFileData(FileData.Type heat, String yaml) {
265 FileData fileData = new FileData();
266 fileData.setType(heat);
267 fileData.setFile(yaml);
271 private FileData createModuleFileData(
272 String moduleFileName, boolean isBase, Set<String> processedFiles,
273 Set<String> fileNames, List<FileData> fileDataList) {
274 FileData moduleFileData = createBasicFileData(moduleFileName, FileData.Type.HEAT, isBase);
275 Optional<String> volFile = fetchRelatedVolume(moduleFileName, fileNames);
276 volFile.ifPresent(vol -> {
277 markFileAsProcessed(vol, processedFiles);
278 removeFromFileDataListIfAlreadyProcessed(fileDataList, vol);
279 FileData volFileData = createBasicFileData(vol, FileData.Type.HEAT_VOL, null);
280 Optional<String> envFile = fetchRelatedEnv(vol, fileNames);
281 envFile.ifPresent(env -> {
282 markFileAsProcessed(env, processedFiles);
283 removeFromFileDataListIfAlreadyProcessed(fileDataList, env);
284 FileData envFileData = createBasicFileData(env, FileData.Type.HEAT_ENV, null);
285 volFileData.addFileData(envFileData);
287 moduleFileData.addFileData(volFileData);
289 Optional<String> envFile = fetchRelatedEnv(moduleFileName, fileNames);
290 envFile.ifPresent(env -> {
291 markFileAsProcessed(env, processedFiles);
292 FileData envFileData = createBasicFileData(env, FileData.Type.HEAT_ENV, null);
293 moduleFileData.addFileData(envFileData);
295 return moduleFileData;
298 private void removeFromFileDataListIfAlreadyProcessed(List<FileData> fileDataList, String vol) {
299 fileDataList.removeIf(fileData -> fileData.getFile().equals(vol));
302 private FileData createBasicFileData(String fileName, FileData.Type type, Boolean isBase) {
303 FileData fileData = new FileData();
304 if (isBase != null) {
305 fileData.setBase(isBase);
307 fileData.setType(type);
308 fileData.setFile(fileName);
312 private Optional<String> fetchRelatedEnv(String fileName, Set<String> fileNames) {
314 = fileName.substring(0, fileName.lastIndexOf(".")) + Constants.ENV_FILE_EXTENSION;
315 return fileNames.contains(envFileName) ? Optional.of(envFileName) : Optional.empty();
318 private Optional<String> fetchRelatedVolume(String fileName, Set<String> fileNames) {
320 String volFile1stExt =
321 extractVolFileName(fileName, ".yaml");
322 String volFile2ndExt =
323 extractVolFileName(fileName, ".yml");
325 if (fileNames.contains(volFile1stExt)) {
326 return Optional.of(volFile1stExt);
328 if (fileNames.contains(volFile2ndExt)) {
329 return Optional.of(volFile2ndExt);
331 return Optional.empty();
334 private String extractVolFileName(String fileName, String fileExt) {
335 return fileName.substring(
336 0, fileName.lastIndexOf("."))
337 + Constants.VOL_FILE_NAME_SUFFIX + fileExt;
341 private boolean isVolFile(String fileName) {
344 Constants.VOL_FILE_NAME_SUFFIX + ".yaml")
345 || fileName.endsWith(Constants.VOL_FILE_NAME_SUFFIX + ".yml");
349 private void markFileAsProcessed(String fileName, Set<String> processedFiles) {
350 processedFiles.add(fileName);