[SDC] Onboarding 1710 rebase.
[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
207                     .addIgnoreNull(filesDataStructure.getUnassigned(), module.getVolEnv());
208             } else {
209                 if (filesDataStructure.getNested().contains(module.getYaml())) {
210                     moveModuleFileToNested(filesDataStructure, i--, module);
211                 }
212             }
213         }
214     }
215
216     private void addFileToUnassigned(FilesDataStructure filesDataStructure, Set<String> zipFileList,
217                                      String fileName) {
218         if (isFileExistInZipContains(zipFileList, fileName)) {
219             filesDataStructure.getUnassigned().add(fileName);
220         }
221     }
222
223     private boolean isFileExistInZipContains(Set<String> zipFileList, String fileName) {
224         return Objects.nonNull(fileName) && zipFileList.contains(fileName);
225     }
226
227     private void moveModuleFileToNested(FilesDataStructure filesDataStructure, int i,
228                                         Module module) {
229         if (!filesDataStructure.getNested().contains(module.getYaml())) {
230             filesDataStructure.getNested().add(module.getYaml());
231         }
232         if (Objects.nonNull(module.getEnv())) {
233             filesDataStructure.getNested().add(module.getEnv());
234         }
235         if (Objects.nonNull(module.getVol())) {
236             filesDataStructure.getNested().add(module.getVol());
237         }
238         if (Objects.nonNull(module.getVolEnv())) {
239             filesDataStructure.getNested().add(module.getVolEnv());
240         }
241         filesDataStructure.getModules().remove(i);
242     }
243
244     private Set<String> getFlatFileNames(FilesDataStructure filesDataStructure) {
245         Set<String> fileNames = new HashSet<>();
246         if (!CollectionUtils.isEmpty(filesDataStructure.getModules())) {
247             for (Module module : filesDataStructure.getModules()) {
248                 CollectionUtils.addIgnoreNull(fileNames, module.getEnv());
249                 CollectionUtils.addIgnoreNull(fileNames, module.getVol());
250                 CollectionUtils.addIgnoreNull(fileNames, module.getVolEnv());
251                 CollectionUtils.addIgnoreNull(fileNames, module.getYaml());
252             }
253         }
254         fileNames.addAll(filesDataStructure.getArtifacts().stream().collect(Collectors.toSet()));
255         fileNames.addAll(filesDataStructure.getNested().stream().collect(Collectors.toSet()));
256         fileNames.addAll(filesDataStructure.getUnassigned().stream().collect(Collectors.toSet()));
257
258         return fileNames;
259     }
260
261     private FilesDataStructure createFileDataStructureFromManifest(InputStream isManifestContent) {
262
263
264         mdcDataDebugMessage.debugEntryMessage(null);
265
266         ManifestContent manifestContent =
267             JsonUtil.json2Object(isManifestContent, ManifestContent.class);
268         FilesDataStructure structure = new FilesDataStructure();
269         for (FileData fileData : manifestContent.getData()) {
270             if (Objects.nonNull(fileData.getType()) &&
271                 fileData.getType().equals(FileData.Type.HEAT)) {
272                 Module module = new Module();
273                 module.setYaml(fileData.getFile());
274                 module.setIsBase(fileData.getBase());
275                 addHeatDependenciesToModule(module, fileData.getData());
276                 structure.getModules().add(module);
277             } else if (HeatFileAnalyzer.isYamlOrEnvFile(fileData.getFile()) &&
278                 !FileData.Type.isArtifact(fileData.getType())) {
279                 structure.getUnassigned().add(fileData.getFile());
280             } else {
281                 structure.getArtifacts().add(fileData.getFile());
282             }
283         }
284
285         mdcDataDebugMessage.debugExitMessage(null);
286         return structure;
287     }
288
289     private void addHeatDependenciesToModule(Module module, List<FileData> data) {
290         if (CollectionUtils.isEmpty(data)) {
291             return;
292         }
293
294         for (FileData fileData : data) {
295             if (fileData.getType().equals(FileData.Type.HEAT_ENV)) {
296                 module.setEnv(fileData.getFile());
297             } else if (fileData.getType().equals(FileData.Type.HEAT_VOL))// must be volume
298             {
299                 module.setVol(fileData.getFile());
300                 if (!CollectionUtils.isEmpty(fileData.getData())) {
301                     FileData volEnv = fileData.getData().get(0);
302                     if (volEnv.getType().equals(FileData.Type.HEAT_ENV)) {
303                         module.setVolEnv(volEnv.getFile());
304                     } else {
305                         throw new CoreException((new ErrorCode.ErrorCodeBuilder())
306                             .withMessage(Messages.ILLEGAL_MANIFEST.getErrorMessage())
307                             .withId(Messages.ILLEGAL_MANIFEST.getErrorMessage())
308                             .withCategory(ErrorCategory.APPLICATION).build());
309                     }
310                 }
311             } else {
312                 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
313                     .withMessage(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
314                     .withId(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
315                     .withCategory(ErrorCategory.APPLICATION).build());
316             }
317         }
318     }
319
320     @Override
321     public void updateCandidateUploadData(OrchestrationTemplateCandidateData uploadData,
322                                           String itemId) {
323         mdcDataDebugMessage.debugEntryMessage(null);
324
325         //vendorSoftwareProductDao.updateCandidateUploadData(uploadData);
326         orchestrationTemplateCandidateDataDao.update(itemId, uploadData);
327
328         mdcDataDebugMessage.debugExitMessage(null);
329     }
330
331     @Override
332     public Optional<FilesDataStructure> getOrchestrationTemplateCandidateFileDataStructure(
333         String vspId, Version version) {
334
335         mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
336
337         Optional<String> jsonFileDataStructure =
338             orchestrationTemplateCandidateDataDao.getStructure(vspId, version);
339
340         if (jsonFileDataStructure.isPresent()) {
341             mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
342             return Optional
343                 .of(JsonUtil.json2Object(jsonFileDataStructure.get(), FilesDataStructure.class));
344         } else {
345             mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
346             return Optional.empty();
347         }
348     }
349
350     @Override
351     public void updateOrchestrationTemplateCandidateFileDataStructure(String vspId, Version version,
352                                                                       FilesDataStructure fileDataStructure) {
353         OrchestrationTemplateCandidateDaoFactory.getInstance().createInterface()
354             .updateStructure(vspId, version, fileDataStructure);
355     }
356
357     @Override
358     public OrchestrationTemplateCandidateData getOrchestrationTemplateCandidate(String vspId,
359                                                                                 Version version) {
360         mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
361         mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
362
363         return orchestrationTemplateCandidateDataDao.get(vspId, version);
364     }
365
366   @Override
367   public String createManifest(VspDetails vspDetails, FilesDataStructure structure) {
368
369         mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
370
371         Optional<ManifestContent> manifest = manifestCreator.createManifest(vspDetails, structure);
372         if (!manifest.isPresent()) {
373             throw new RuntimeException(Messages.CREATE_MANIFEST_FROM_ZIP.getErrorMessage());
374         }
375
376         mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
377         return JsonUtil.object2Json(manifest.get());
378     }
379
380     @Override
381     public Optional<ManifestContent> createManifest(VspDetails vspDetails,
382                                                     FileContentHandler fileContentHandler,
383                                                     AnalyzedZipHeatFiles analyzedZipHeatFiles) {
384
385
386         mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
387
388         mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
389         return manifestCreator.createManifest(vspDetails, fileContentHandler, analyzedZipHeatFiles);
390     }
391
392     @Override
393     public Optional<ByteArrayInputStream> fetchZipFileByteArrayInputStream(String vspId,
394                                                                            OrchestrationTemplateCandidateData candidateDataEntity,
395                                                                            String manifest,
396                                                                            Map<String, List<ErrorMessage>> uploadErrors) {
397         byte[] file;
398         ByteArrayInputStream byteArrayInputStream = null;
399         try {
400             file = replaceManifestInZip(candidateDataEntity.getContentData(), manifest, vspId);
401             byteArrayInputStream = new ByteArrayInputStream(
402                 Objects.isNull(file) ? candidateDataEntity.getContentData().array()
403                     : file);
404         } catch (IOException e) {
405             ErrorMessage errorMessage =
406                 new ErrorMessage(ErrorLevel.ERROR,
407                     Messages.CANDIDATE_PROCESS_FAILED.getErrorMessage());
408             logger.error(errorMessage.getMessage(), e);
409             ErrorsUtil
410                 .addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE, errorMessage, uploadErrors);
411         }
412         return Optional.ofNullable(byteArrayInputStream);
413     }
414
415     @Override
416     public byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, String vspId)
417         throws IOException {
418         ByteArrayOutputStream baos = new ByteArrayOutputStream();
419
420         try (final ZipOutputStream zos = new ZipOutputStream(baos);
421              ZipInputStream zipStream = new ZipInputStream(
422                  new ByteArrayInputStream(contentData.array()))) {
423             ZipEntry zipEntry;
424             boolean manifestWritten = false;
425             while ((zipEntry = zipStream.getNextEntry()) != null) {
426                 if (!zipEntry.getName().equalsIgnoreCase(SdcCommon.MANIFEST_NAME)) {
427                     ZipEntry loc_ze = new ZipEntry(zipEntry.getName());
428                     zos.putNextEntry(loc_ze);
429                     byte[] buf = new byte[1024];
430                     int len;
431                     while ((len = zipStream.read(buf)) > 0) {
432                         zos.write(buf, 0, (len < buf.length) ? len : buf.length);
433                     }
434                 } else {
435                     manifestWritten = true;
436                     writeManifest(manifest, zos);
437                 }
438                 zos.closeEntry();
439             }
440             if (!manifestWritten) {
441                 writeManifest(manifest, zos);
442                 zos.closeEntry();
443             }
444         }
445         return baos.toByteArray();
446     }
447
448     @Override
449     public Optional<List<ErrorMessage>> validateFileDataStructure(
450         FilesDataStructure filesDataStructure) {
451         return candidateServiceValidator.validateFileDataStructure(filesDataStructure);
452     }
453
454     private void writeManifest(String manifest, ZipOutputStream zos) throws IOException {
455         zos.putNextEntry(new ZipEntry(SdcCommon.MANIFEST_NAME));
456         try (InputStream manifestStream = new ByteArrayInputStream(
457             manifest.getBytes(StandardCharsets.UTF_8))) {
458             byte[] buf = new byte[1024];
459             int len;
460             while ((len = (manifestStream.read(buf))) > 0) {
461                 zos.write(buf, 0, (len < buf.length) ? len : buf.length);
462             }
463         }
464     }
465
466     private void handleArtifactsFromTree(HeatStructureTree tree, FilesDataStructure structure) {
467
468         if (Objects.isNull(tree) || Objects.isNull(tree.getArtifacts())) {
469             return;
470         }
471
472         if (CollectionUtils.isNotEmpty(tree.getArtifacts())) {
473             structure.getArtifacts().addAll(
474                 tree.getArtifacts()
475                     .stream()
476                     .map(Artifact::getFileName)
477                     .filter(fileName -> !structure.getArtifacts().contains(fileName))
478                     .collect(Collectors.toList()));
479         }
480     }
481
482     private void handleOtherResources(HeatStructureTree tree, Set<String> usedEnvFiles,
483                                       FilesDataStructure structure) {
484         Set<HeatStructureTree> others = tree.getOther();
485         if (Objects.isNull(others)) {
486             return;
487         }
488
489         List<String> artifacts = new ArrayList<>();
490         List<String> unassigned = new ArrayList<>();
491         for (HeatStructureTree other : others) {
492             if (HeatFileAnalyzer.isYamlOrEnvFile(other.getFileName())) {
493                 if (isEnvFileUsedByHeatFile(usedEnvFiles, other)) {
494                     continue;
495                 }
496                 unassigned.add(other.getFileName());
497             } else {
498                 artifacts.add(other.getFileName());
499             }
500             handleArtifactsFromTree(other, structure);
501         }
502         structure.getArtifacts().addAll(artifacts);
503         structure.getUnassigned().addAll(unassigned);
504     }
505
506     private boolean isEnvFileUsedByHeatFile(Set<String> usedEnvFiles, HeatStructureTree other) {
507         if (HeatFileAnalyzer.isEnvFile(other.getFileName())) {
508             if (usedEnvFiles.contains(other.getFileName())) {
509                 return true;
510             }
511         }
512         return false;
513     }
514
515     private void addHeatsToFileDataStructure(HeatStructureTree tree, Set<String> usedEnvFiles,
516                                              FilesDataStructure structure,
517                                              Map<String, List<ErrorMessage>> uploadErrors,
518                                              AnalyzedZipHeatFiles analyzedZipHeatFiles)
519         throws Exception {
520         List<Module> modules = new ArrayList<>();
521         Set<HeatStructureTree> heatsSet = tree.getHeat();
522         if (Objects.isNull(heatsSet)) {
523             return;
524         }
525         for (HeatStructureTree heat : heatsSet) {
526             if (isFileBaseFile(heat.getFileName())) {
527                 handleSingleHeat(structure, modules, heat, uploadErrors);
528             } else if (isFileModuleFile(heat.getFileName(),
529                 analyzedZipHeatFiles.getModuleFiles())) {
530                 handleSingleHeat(structure, modules, heat, uploadErrors);
531             } else {
532                 structure.getUnassigned().add(heat.getFileName());
533                 addNestedToFileDataStructure(heat, structure);
534             }
535             if (!Objects.isNull(heat.getEnv())) {
536                 usedEnvFiles.add(heat.getEnv() == null ? null : heat.getEnv().getFileName());
537             }
538         }
539         structure.setModules(modules);
540
541     }
542
543     private boolean isFileModuleFile(String fileName, Set<String> modulesFileNames) {
544         return modulesFileNames.contains(fileName);
545     }
546
547     private boolean isFileBaseFile(String fileName) {
548         return manifestCreator.isFileBaseFile(fileName);
549     }
550
551     private void handleSingleHeat(FilesDataStructure structure, List<Module> modules,
552                                   HeatStructureTree heat,
553                                   Map<String, List<ErrorMessage>> uploadErrors) {
554
555
556         mdcDataDebugMessage.debugEntryMessage(null);
557
558         Module module = new Module();
559         module.setYaml(heat.getFileName());
560         module.setIsBase(heat.getBase());
561         addNestedToFileDataStructure(heat, structure);
562         Set<HeatStructureTree> volumeSet = heat.getVolume();
563         int inx = 0;
564         if (Objects.nonNull(volumeSet)) {
565             handleVolumes(module, volumeSet, structure, inx, uploadErrors);
566         }
567         handleEnv(module, heat, false, structure);
568         modules.add(module);
569
570         mdcDataDebugMessage.debugExitMessage(null);
571     }
572
573     private void handleVolumes(Module module, Set<HeatStructureTree> volumeSet,
574                                FilesDataStructure structure, int inx,
575                                Map<String, List<ErrorMessage>> uploadErrors) {
576
577
578         mdcDataDebugMessage.debugEntryMessage(null);
579
580         for (HeatStructureTree volume : volumeSet) {
581             if (inx++ > 0) {
582                 ErrorsUtil.addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE,
583                     new ErrorMessage(ErrorLevel.WARNING,
584                         Messages.MORE_THEN_ONE_VOL_FOR_HEAT.getErrorMessage()), uploadErrors);
585                 break;
586             }
587             handleArtifactsFromTree(volume, structure);
588             module.setVol(volume.getFileName());
589             handleEnv(module, volume, true, structure);
590         }
591
592         mdcDataDebugMessage.debugExitMessage(null);
593     }
594
595     private void handleEnv(Module module, HeatStructureTree tree, boolean isVolEnv,
596                            FilesDataStructure structure) {
597
598
599         mdcDataDebugMessage.debugEntryMessage(null);
600
601         if (Objects.nonNull(tree.getEnv())) {
602             if (isVolEnv) {
603                 module.setVolEnv(tree.getEnv().getFileName());
604             } else {
605                 module.setEnv(tree.getEnv().getFileName());
606             }
607             handleArtifactsFromTree(tree.getEnv(), structure);
608         }
609
610         mdcDataDebugMessage.debugExitMessage(null);
611     }
612
613     private void addNestedToFileDataStructure(HeatStructureTree heat,
614                                               FilesDataStructure structure) {
615         Set<HeatStructureTree> nestedSet = heat.getNested();
616         if (Objects.isNull(nestedSet)) {
617             return;
618         }
619         for (HeatStructureTree nested : nestedSet) {
620             if (structure.getNested().contains(nested.getFileName())) {
621                 continue;
622             }
623             structure.getNested().add(nested.getFileName());
624             if (CollectionUtils.isNotEmpty(nested.getArtifacts())) {
625                 handleArtifactsFromTree(nested, structure);
626             }
627             addNestedToFileDataStructure(nested, structure);
628         }
629     }
630 }