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