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