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