e05c84845259d60ec2b2ea23df38d60565286101
[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 / CandidateServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.vendorsoftwareproduct.services.impl.filedatastructuremodule;
22
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.openecomp.core.utilities.file.FileContentHandler;
25 import org.openecomp.core.utilities.json.JsonUtil;
26 import org.openecomp.sdc.common.errors.CoreException;
27 import org.openecomp.sdc.common.errors.ErrorCategory;
28 import org.openecomp.sdc.common.errors.ErrorCode;
29 import org.openecomp.sdc.common.errors.Messages;
30 import org.openecomp.sdc.common.utils.SdcCommon;
31 import org.openecomp.sdc.datatypes.error.ErrorLevel;
32 import org.openecomp.sdc.datatypes.error.ErrorMessage;
33 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
34 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
35 import org.openecomp.sdc.heat.datatypes.structure.Artifact;
36 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
37 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
38 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateCandidateDao;
39 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateCandidateDaoFactory;
40 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData;
41 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
42 import org.openecomp.sdc.vendorsoftwareproduct.errors.utils.ErrorsUtil;
43 import org.openecomp.sdc.vendorsoftwareproduct.services.HeatFileAnalyzer;
44 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.CandidateService;
45 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.ManifestCreator;
46 import org.openecomp.sdc.vendorsoftwareproduct.services.utils.CandidateServiceValidator;
47 import org.openecomp.sdc.vendorsoftwareproduct.types.CandidateDataEntityTo;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.AnalyzedZipHeatFiles;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
50 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.Module;
51 import org.openecomp.sdc.versioning.dao.types.Version;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import java.io.ByteArrayInputStream;
56 import java.io.ByteArrayOutputStream;
57 import java.io.IOException;
58 import java.io.InputStream;
59 import java.nio.ByteBuffer;
60 import java.nio.charset.StandardCharsets;
61 import java.util.ArrayList;
62 import java.util.HashSet;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Objects;
66 import java.util.Optional;
67 import java.util.Set;
68 import java.util.stream.Collectors;
69 import java.util.zip.ZipEntry;
70 import java.util.zip.ZipInputStream;
71 import java.util.zip.ZipOutputStream;
72
73 public class CandidateServiceImpl implements CandidateService {
74   protected static final Logger logger = LoggerFactory.getLogger(CandidateServiceImpl.class);
75   private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
76
77   private CandidateServiceValidator candidateServiceValidator = new CandidateServiceValidator();
78   private ManifestCreator manifestCreator;
79   private OrchestrationTemplateCandidateDao orchestrationTemplateCandidateDataDao;
80
81   public CandidateServiceImpl(ManifestCreator manifestCreator,
82                               OrchestrationTemplateCandidateDao orchestrationTemplateCandidateDataDao) {
83     this.manifestCreator = manifestCreator;
84     this.orchestrationTemplateCandidateDataDao = orchestrationTemplateCandidateDataDao;
85
86   }
87
88   public CandidateServiceImpl() {
89   }
90
91   @Override
92   public Optional<ErrorMessage> validateNonEmptyFileToUpload(InputStream heatFileToUpload) {
93
94
95     mdcDataDebugMessage.debugEntryMessage(null);
96
97     if (Objects.isNull(heatFileToUpload)) {
98       return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
99           Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
100     } else {
101       try {
102         int available = heatFileToUpload.available();
103         if (available == 0) {
104           mdcDataDebugMessage.debugExitMessage(null);
105           return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
106               Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
107         }
108       } catch (IOException e) {
109         mdcDataDebugMessage.debugExitMessage(null);
110         return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
111             Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
112       }
113     }
114
115     mdcDataDebugMessage.debugExitMessage(null);
116     return Optional.empty();
117   }
118
119   @Override
120   public Optional<ErrorMessage> validateRawZipData(byte[] uploadedFileData) {
121     if (Objects.isNull(uploadedFileData)) {
122       return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
123           Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
124     }
125     return Optional.empty();
126   }
127
128   private String heatStructureTreeToFileDataStructure(HeatStructureTree tree,
129                                                       FileContentHandler zipContentMap,
130                                                       Map<String, List<ErrorMessage>> uploadErrors,
131                                                       AnalyzedZipHeatFiles analyzedZipHeatFiles)
132       throws Exception {
133     FilesDataStructure structure = new FilesDataStructure();
134     Set<String> usedEnvFiles = new HashSet<>();
135     addHeatsToFileDataStructure(tree, usedEnvFiles, structure, uploadErrors,
136         analyzedZipHeatFiles);
137     handleOtherResources(tree, usedEnvFiles, structure);
138     FilesDataStructure fileDataStructureFromManifest =
139         createFileDataStructureFromManifest(zipContentMap.getFileContent
140             (SdcCommon.MANIFEST_NAME));
141     List<String> structureArtifacts = structure.getArtifacts();
142     structureArtifacts.addAll(fileDataStructureFromManifest.getArtifacts().stream().filter
143         (artifact -> !structureArtifacts.contains(artifact)).collect((Collectors.toList())));
144     handleArtifactsFromTree(tree, structure);
145
146     return JsonUtil.object2Json(structure);
147   }
148
149   @Override
150   public OrchestrationTemplateCandidateData createCandidateDataEntity(
151       CandidateDataEntityTo candidateDataEntityTo, InputStream zipFileManifest,
152       AnalyzedZipHeatFiles analyzedZipHeatFiles) throws Exception {
153
154
155     mdcDataDebugMessage.debugEntryMessage(null);
156
157     FileContentHandler zipContentMap = candidateDataEntityTo.getContentMap();
158     FilesDataStructure filesDataStructure;
159     String dataStructureJson;
160
161     if (zipFileManifest != null) {
162       // create data structure from manifest
163       filesDataStructure = createFileDataStructureFromManifest(zipFileManifest);
164       Set<String> zipFileList = zipContentMap.getFileList();
165       balanceManifestFilesWithZipFiles(filesDataStructure,
166           zipContentMap, analyzedZipHeatFiles);
167       Set<String> filesDataStructureFiles = getFlatFileNames(filesDataStructure);
168       filesDataStructure.getUnassigned().addAll(zipFileList.stream()
169           .filter(fileName -> (!filesDataStructureFiles.contains(fileName) &&
170               !filesDataStructure.getNested().contains(fileName) &&
171               !fileName.equals(SdcCommon.MANIFEST_NAME)))
172           .collect(Collectors.toList()));
173       dataStructureJson = JsonUtil.object2Json(filesDataStructure);
174     } else {
175       // create data structure from based on naming convention
176       dataStructureJson =
177           heatStructureTreeToFileDataStructure(candidateDataEntityTo.getTree(), zipContentMap,
178               candidateDataEntityTo.getErrors(), analyzedZipHeatFiles);
179     }
180
181     mdcDataDebugMessage.debugExitMessage(null);
182     return new OrchestrationTemplateCandidateData(
183         ByteBuffer.wrap(candidateDataEntityTo.getUploadedFileData()), dataStructureJson);
184   }
185
186   private void balanceManifestFilesWithZipFiles(
187       FilesDataStructure filesDataStructure,
188       FileContentHandler fileContentHandler, AnalyzedZipHeatFiles analyzedZipHeatFiles)
189       throws Exception {
190     Set<String> zipFileList = fileContentHandler.getFileList();
191     filesDataStructure.getNested().addAll(analyzedZipHeatFiles.getNestedFiles());
192     List<Module> modules = filesDataStructure.getModules();
193     if (CollectionUtils.isEmpty(modules)) {
194       return;
195     }
196
197     for (int i = 0; i < modules.size(); i++) {
198       Module module = modules.get(i);
199       if (!isFileExistInZipContains(zipFileList, module.getYaml())) {
200         addFileToUnassigned(filesDataStructure, zipFileList, module.getEnv());
201         addFileToUnassigned(filesDataStructure, zipFileList, module.getVol());
202         addFileToUnassigned(filesDataStructure, zipFileList, module.getVolEnv());
203         modules.remove(i--);
204       } else if (Objects.nonNull(module.getVol()) && !zipFileList.contains(module.getVol())) {
205         module.setVol(null);
206         CollectionUtils.addIgnoreNull(filesDataStructure.getUnassigned(), module.getVolEnv());
207       } else {
208         if (filesDataStructure.getNested().contains(module.getYaml())) {
209           moveModuleFileToNested(filesDataStructure, i--, module);
210         }
211       }
212     }
213   }
214
215   private void addFileToUnassigned(FilesDataStructure filesDataStructure, Set<String> zipFileList,
216                                    String fileName) {
217     if (isFileExistInZipContains(zipFileList, fileName)) {
218       filesDataStructure.getUnassigned().add(fileName);
219     }
220   }
221
222   private boolean isFileExistInZipContains(Set<String> zipFileList, String fileName) {
223     return Objects.nonNull(fileName) && zipFileList.contains(fileName);
224   }
225
226   private void moveModuleFileToNested(FilesDataStructure filesDataStructure, int i, Module module) {
227     if (!filesDataStructure.getNested().contains(module.getYaml())) {
228       filesDataStructure.getNested().add(module.getYaml());
229     }
230     if (Objects.nonNull(module.getEnv())) {
231       filesDataStructure.getNested().add(module.getEnv());
232     }
233     if (Objects.nonNull(module.getVol())) {
234       filesDataStructure.getNested().add(module.getVol());
235     }
236     if (Objects.nonNull(module.getVolEnv())) {
237       filesDataStructure.getNested().add(module.getVolEnv());
238     }
239     filesDataStructure.getModules().remove(i);
240   }
241
242   private Set<String> getFlatFileNames(FilesDataStructure filesDataStructure) {
243     Set<String> fileNames = new HashSet<>();
244     if (!CollectionUtils.isEmpty(filesDataStructure.getModules())) {
245       for (Module module : filesDataStructure.getModules()) {
246         CollectionUtils.addIgnoreNull(fileNames, module.getEnv());
247         CollectionUtils.addIgnoreNull(fileNames, module.getVol());
248         CollectionUtils.addIgnoreNull(fileNames, module.getVolEnv());
249         CollectionUtils.addIgnoreNull(fileNames, module.getYaml());
250       }
251     }
252     fileNames.addAll(filesDataStructure.getArtifacts().stream().collect(Collectors.toSet()));
253     fileNames.addAll(filesDataStructure.getNested().stream().collect(Collectors.toSet()));
254     fileNames.addAll(filesDataStructure.getUnassigned().stream().collect(Collectors.toSet()));
255
256     return fileNames;
257   }
258
259   private FilesDataStructure createFileDataStructureFromManifest(InputStream isManifestContent) {
260
261
262     mdcDataDebugMessage.debugEntryMessage(null);
263
264     ManifestContent manifestContent =
265         JsonUtil.json2Object(isManifestContent, ManifestContent.class);
266     FilesDataStructure structure = new FilesDataStructure();
267     for (FileData fileData : manifestContent.getData()) {
268       if (Objects.nonNull(fileData.getType()) && fileData.getType().equals(FileData.Type.HEAT)) {
269         Module module = new Module();
270         module.setYaml(fileData.getFile());
271         module.setIsBase(fileData.getBase());
272         addHeatDependenciesToModule(module, fileData.getData());
273         structure.getModules().add(module);
274       } else if (HeatFileAnalyzer.isYamlOrEnvFile(fileData.getFile()) &&
275           !FileData.Type.isArtifact(fileData.getType())) {
276         structure.getUnassigned().add(fileData.getFile());
277       } else {
278         structure.getArtifacts().add(fileData.getFile());
279       }
280     }
281
282     mdcDataDebugMessage.debugExitMessage(null);
283     return structure;
284   }
285
286   private void addHeatDependenciesToModule(Module module, List<FileData> data) {
287     if (CollectionUtils.isEmpty(data)) {
288       return;
289     }
290
291     for (FileData fileData : data) {
292       if (fileData.getType().equals(FileData.Type.HEAT_ENV)) {
293         module.setEnv(fileData.getFile());
294       } else if (fileData.getType().equals(FileData.Type.HEAT_VOL))// must be volume
295       {
296         module.setVol(fileData.getFile());
297         if (!CollectionUtils.isEmpty(fileData.getData())) {
298           FileData volEnv = fileData.getData().get(0);
299           if (volEnv.getType().equals(FileData.Type.HEAT_ENV)) {
300             module.setVolEnv(volEnv.getFile());
301           } else {
302             throw new CoreException((new ErrorCode.ErrorCodeBuilder())
303                 .withMessage(Messages.ILLEGAL_MANIFEST.getErrorMessage())
304                 .withId(Messages.ILLEGAL_MANIFEST.getErrorMessage())
305                 .withCategory(ErrorCategory.APPLICATION).build());
306           }
307         }
308       } else {
309         throw new CoreException((new ErrorCode.ErrorCodeBuilder())
310             .withMessage(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
311             .withId(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
312             .withCategory(ErrorCategory.APPLICATION).build());
313       }
314     }
315   }
316
317   @Override
318   public void updateCandidateUploadData(OrchestrationTemplateCandidateData uploadData,
319                                         String itemId) {
320     mdcDataDebugMessage.debugEntryMessage(null);
321
322     //vendorSoftwareProductDao.updateCandidateUploadData(uploadData);
323     orchestrationTemplateCandidateDataDao.update(itemId, uploadData);
324
325     mdcDataDebugMessage.debugExitMessage(null);
326   }
327
328   @Override
329   public Optional<FilesDataStructure> getOrchestrationTemplateCandidateFileDataStructure(
330       String vspId, Version version) {
331
332     mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
333
334     Optional<String> jsonFileDataStructure =
335         orchestrationTemplateCandidateDataDao.getStructure(vspId, version);
336
337     if (jsonFileDataStructure.isPresent()) {
338       mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
339       return Optional
340           .of(JsonUtil.json2Object(jsonFileDataStructure.get(), FilesDataStructure.class));
341     } else {
342       mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
343       return Optional.empty();
344     }
345   }
346
347   @Override
348   public void updateOrchestrationTemplateCandidateFileDataStructure(String vspId, Version version,
349                                                                     FilesDataStructure fileDataStructure) {
350     OrchestrationTemplateCandidateDaoFactory.getInstance().createInterface()
351         .updateStructure(vspId, version, fileDataStructure);
352   }
353
354   @Override
355   public OrchestrationTemplateCandidateData getOrchestrationTemplateCandidate(String vspId,
356                                                                               Version version) {
357     mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
358     mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
359
360     return orchestrationTemplateCandidateDataDao.get(vspId, version);
361   }
362
363   @Override
364   public String createManifest(VspDetails vspDetails, FilesDataStructure structure) {
365
366     mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
367
368     Optional<ManifestContent> manifest = manifestCreator.createManifest(vspDetails, structure);
369     if (!manifest.isPresent()) {
370       throw new RuntimeException(Messages.CREATE_MANIFEST_FROM_ZIP.getErrorMessage());
371     }
372
373     mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
374     return JsonUtil.object2Json(manifest.get());
375   }
376
377   @Override
378   public Optional<ManifestContent> createManifest(VspDetails vspDetails,
379                                                   FileContentHandler fileContentHandler,
380                                                   AnalyzedZipHeatFiles analyzedZipHeatFiles) {
381
382
383     mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
384
385     mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
386     return manifestCreator.createManifest(vspDetails, fileContentHandler, analyzedZipHeatFiles);
387   }
388
389   @Override
390   public Optional<ByteArrayInputStream> fetchZipFileByteArrayInputStream(String vspId,
391                                                                          OrchestrationTemplateCandidateData candidateDataEntity,
392                                                                          String manifest,
393                                                                          Map<String, List<ErrorMessage>> uploadErrors) {
394     byte[] file;
395     ByteArrayInputStream byteArrayInputStream = null;
396     try {
397       file = replaceManifestInZip(candidateDataEntity.getContentData(), manifest, vspId);
398       byteArrayInputStream = new ByteArrayInputStream(
399           Objects.isNull(file) ? candidateDataEntity.getContentData().array()
400               : file);
401     } catch (IOException e) {
402       ErrorMessage errorMessage =
403           new ErrorMessage(ErrorLevel.ERROR, Messages.CANDIDATE_PROCESS_FAILED.getErrorMessage());
404       logger.error(errorMessage.getMessage(), e);
405       ErrorsUtil.addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE, errorMessage, uploadErrors);
406     }
407     return Optional.ofNullable(byteArrayInputStream);
408   }
409
410   @Override
411   public byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, String vspId)
412       throws IOException {
413     ByteArrayOutputStream baos = new ByteArrayOutputStream();
414
415     try (final ZipOutputStream zos = new ZipOutputStream(baos);
416          ZipInputStream zipStream = new ZipInputStream(
417              new ByteArrayInputStream(contentData.array()))) {
418       ZipEntry zipEntry;
419       boolean manifestWritten = false;
420       while ((zipEntry = zipStream.getNextEntry()) != null) {
421         if (!zipEntry.getName().equalsIgnoreCase(SdcCommon.MANIFEST_NAME)) {
422           ZipEntry loc_ze = new ZipEntry(zipEntry.getName());
423           zos.putNextEntry(loc_ze);
424           byte[] buf = new byte[1024];
425           int len;
426           while ((len = zipStream.read(buf)) > 0) {
427             zos.write(buf, 0, (len < buf.length) ? len : buf.length);
428           }
429         } else {
430           manifestWritten = true;
431           writeManifest(manifest, zos);
432         }
433         zos.closeEntry();
434       }
435       if (!manifestWritten) {
436         writeManifest(manifest, zos);
437         zos.closeEntry();
438       }
439     }
440     return baos.toByteArray();
441   }
442
443   @Override
444   public Optional<List<ErrorMessage>> validateFileDataStructure(
445       FilesDataStructure filesDataStructure) {
446     return candidateServiceValidator.validateFileDataStructure(filesDataStructure);
447   }
448
449   private void writeManifest(String manifest, ZipOutputStream zos) throws IOException {
450     zos.putNextEntry(new ZipEntry(SdcCommon.MANIFEST_NAME));
451     try (InputStream manifestStream = new ByteArrayInputStream(
452         manifest.getBytes(StandardCharsets.UTF_8))) {
453       byte[] buf = new byte[1024];
454       int len;
455       while ((len = (manifestStream.read(buf))) > 0) {
456         zos.write(buf, 0, (len < buf.length) ? len : buf.length);
457       }
458     }
459   }
460
461   private void handleArtifactsFromTree(HeatStructureTree tree, FilesDataStructure structure) {
462
463     if (Objects.isNull(tree) || Objects.isNull(tree.getArtifacts())) {
464       return;
465     }
466
467     if (CollectionUtils.isNotEmpty(tree.getArtifacts())) {
468       structure.getArtifacts().addAll(
469           tree.getArtifacts()
470               .stream()
471               .map(Artifact::getFileName)
472               .filter(fileName -> !structure.getArtifacts().contains(fileName))
473               .collect(Collectors.toList()));
474     }
475   }
476
477   private void handleOtherResources(HeatStructureTree tree, Set<String> usedEnvFiles,
478                                     FilesDataStructure structure) {
479     Set<HeatStructureTree> others = tree.getOther();
480     if (Objects.isNull(others)) {
481       return;
482     }
483
484     List<String> artifacts = new ArrayList<>();
485     List<String> unassigned = new ArrayList<>();
486     for (HeatStructureTree other : others) {
487       if (HeatFileAnalyzer.isYamlOrEnvFile(other.getFileName())) {
488         if (isEnvFileUsedByHeatFile(usedEnvFiles, other)) {
489           continue;
490         }
491         unassigned.add(other.getFileName());
492       } else {
493         artifacts.add(other.getFileName());
494       }
495       handleArtifactsFromTree(other, structure);
496     }
497     structure.getArtifacts().addAll(artifacts);
498     structure.getUnassigned().addAll(unassigned);
499   }
500
501   private boolean isEnvFileUsedByHeatFile(Set<String> usedEnvFiles, HeatStructureTree other) {
502     if (HeatFileAnalyzer.isEnvFile(other.getFileName())) {
503       if (usedEnvFiles.contains(other.getFileName())) {
504         return true;
505       }
506     }
507     return false;
508   }
509
510   private void addHeatsToFileDataStructure(HeatStructureTree tree, Set<String> usedEnvFiles,
511                                            FilesDataStructure structure,
512                                            Map<String, List<ErrorMessage>> uploadErrors,
513                                            AnalyzedZipHeatFiles analyzedZipHeatFiles)
514       throws Exception {
515     List<Module> modules = new ArrayList<>();
516     Set<HeatStructureTree> heatsSet = tree.getHeat();
517     if (Objects.isNull(heatsSet)) {
518       return;
519     }
520     for (HeatStructureTree heat : heatsSet) {
521       if (isFileBaseFile(heat.getFileName())) {
522         handleSingleHeat(structure, modules, heat, uploadErrors);
523       } else if (isFileModuleFile(heat.getFileName(), analyzedZipHeatFiles.getModuleFiles())) {
524         handleSingleHeat(structure, modules, heat, uploadErrors);
525       } else {
526         structure.getUnassigned().add(heat.getFileName());
527         addNestedToFileDataStructure(heat, structure);
528       }
529       if (!Objects.isNull(heat.getEnv())) {
530         usedEnvFiles.add(heat.getEnv() == null ? null : heat.getEnv().getFileName());
531       }
532     }
533     structure.setModules(modules);
534
535   }
536
537   private boolean isFileModuleFile(String fileName, Set<String> modulesFileNames) {
538     return modulesFileNames.contains(fileName);
539   }
540
541   private boolean isFileBaseFile(String fileName) {
542     return manifestCreator.isFileBaseFile(fileName);
543   }
544
545   private void handleSingleHeat(FilesDataStructure structure, List<Module> modules,
546                                 HeatStructureTree heat,
547                                 Map<String, List<ErrorMessage>> uploadErrors) {
548
549
550     mdcDataDebugMessage.debugEntryMessage(null);
551
552     Module module = new Module();
553     module.setYaml(heat.getFileName());
554     module.setIsBase(heat.getBase());
555     addNestedToFileDataStructure(heat, structure);
556     Set<HeatStructureTree> volumeSet = heat.getVolume();
557     int inx = 0;
558     if (Objects.nonNull(volumeSet)) {
559       handleVolumes(module, volumeSet, structure, inx, uploadErrors);
560     }
561     handleEnv(module, heat, false, structure);
562     modules.add(module);
563
564     mdcDataDebugMessage.debugExitMessage(null);
565   }
566
567   private void handleVolumes(Module module, Set<HeatStructureTree> volumeSet,
568                              FilesDataStructure structure, int inx,
569                              Map<String, List<ErrorMessage>> uploadErrors) {
570
571
572     mdcDataDebugMessage.debugEntryMessage(null);
573
574     for (HeatStructureTree volume : volumeSet) {
575       if (inx++ > 0) {
576         ErrorsUtil.addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE,
577             new ErrorMessage(ErrorLevel.WARNING,
578                 Messages.MORE_THEN_ONE_VOL_FOR_HEAT.getErrorMessage()), uploadErrors);
579         break;
580       }
581       handleArtifactsFromTree(volume, structure);
582       module.setVol(volume.getFileName());
583       handleEnv(module, volume, true, structure);
584     }
585
586     mdcDataDebugMessage.debugExitMessage(null);
587   }
588
589   private void handleEnv(Module module, HeatStructureTree tree, boolean isVolEnv,
590                          FilesDataStructure structure) {
591
592
593     mdcDataDebugMessage.debugEntryMessage(null);
594
595     if (Objects.nonNull(tree.getEnv())) {
596       if (isVolEnv) {
597         module.setVolEnv(tree.getEnv().getFileName());
598       } else {
599         module.setEnv(tree.getEnv().getFileName());
600       }
601       handleArtifactsFromTree(tree.getEnv(), structure);
602     }
603
604     mdcDataDebugMessage.debugExitMessage(null);
605   }
606
607   private void addNestedToFileDataStructure(HeatStructureTree heat, FilesDataStructure structure) {
608     Set<HeatStructureTree> nestedSet = heat.getNested();
609     if (Objects.isNull(nestedSet)) {
610       return;
611     }
612     for (HeatStructureTree nested : nestedSet) {
613       if (structure.getNested().contains(nested.getFileName())) {
614         continue;
615       }
616       structure.getNested().add(nested.getFileName());
617       if (CollectionUtils.isNotEmpty(nested.getArtifacts())) {
618         handleArtifactsFromTree(nested, structure);
619       }
620       addNestedToFileDataStructure(nested, structure);
621     }
622   }
623 }