2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.vendorsoftwareproduct.services.impl.filedatastructuremodule;
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.openecomp.core.utilities.file.FileContentHandler;
25 import org.openecomp.core.utilities.json.JsonUtil;
26 import org.openecomp.sdc.common.errors.CoreException;
27 import org.openecomp.sdc.common.errors.ErrorCategory;
28 import org.openecomp.sdc.common.errors.ErrorCode;
29 import org.openecomp.sdc.common.errors.Messages;
30 import org.openecomp.sdc.common.utils.SdcCommon;
31 import org.openecomp.sdc.datatypes.error.ErrorLevel;
32 import org.openecomp.sdc.datatypes.error.ErrorMessage;
33 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
34 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
35 import org.openecomp.sdc.heat.datatypes.structure.Artifact;
36 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
37 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
38 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateCandidateDao;
39 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateCandidateDaoFactory;
40 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData;
41 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
42 import org.openecomp.sdc.vendorsoftwareproduct.errors.utils.ErrorsUtil;
43 import org.openecomp.sdc.vendorsoftwareproduct.services.HeatFileAnalyzer;
44 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.CandidateService;
45 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.ManifestCreator;
46 import org.openecomp.sdc.vendorsoftwareproduct.services.utils.CandidateServiceValidator;
47 import org.openecomp.sdc.vendorsoftwareproduct.types.CandidateDataEntityTo;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.AnalyzedZipHeatFiles;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
50 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.Module;
51 import org.openecomp.sdc.versioning.dao.types.Version;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import java.io.ByteArrayInputStream;
56 import java.io.ByteArrayOutputStream;
57 import java.io.IOException;
58 import java.io.InputStream;
59 import java.nio.ByteBuffer;
60 import java.nio.charset.StandardCharsets;
61 import java.util.ArrayList;
62 import java.util.HashSet;
63 import java.util.List;
65 import java.util.Objects;
66 import java.util.Optional;
68 import java.util.stream.Collectors;
69 import java.util.zip.ZipEntry;
70 import java.util.zip.ZipInputStream;
71 import java.util.zip.ZipOutputStream;
73 public class CandidateServiceImpl implements CandidateService {
74 protected static final Logger logger = LoggerFactory.getLogger(CandidateServiceImpl.class);
75 private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
77 private CandidateServiceValidator candidateServiceValidator = new CandidateServiceValidator();
78 private ManifestCreator manifestCreator;
79 private OrchestrationTemplateCandidateDao orchestrationTemplateCandidateDataDao;
81 public CandidateServiceImpl(ManifestCreator manifestCreator,
82 OrchestrationTemplateCandidateDao orchestrationTemplateCandidateDataDao) {
83 this.manifestCreator = manifestCreator;
84 this.orchestrationTemplateCandidateDataDao = orchestrationTemplateCandidateDataDao;
88 public CandidateServiceImpl() {
92 public Optional<ErrorMessage> validateNonEmptyFileToUpload(InputStream heatFileToUpload) {
95 mdcDataDebugMessage.debugEntryMessage(null);
97 if (Objects.isNull(heatFileToUpload)) {
98 return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
99 Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
102 int available = heatFileToUpload.available();
103 if (available == 0) {
104 mdcDataDebugMessage.debugExitMessage(null);
105 return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
106 Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
108 } catch (IOException e) {
109 mdcDataDebugMessage.debugExitMessage(null);
110 return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
111 Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
115 mdcDataDebugMessage.debugExitMessage(null);
116 return Optional.empty();
120 public Optional<ErrorMessage> validateRawZipData(byte[] uploadedFileData) {
121 if (Objects.isNull(uploadedFileData)) {
122 return Optional.of(new ErrorMessage(ErrorLevel.ERROR,
123 Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage()));
125 return Optional.empty();
128 private String heatStructureTreeToFileDataStructure(HeatStructureTree tree,
129 FileContentHandler zipContentMap,
130 Map<String, List<ErrorMessage>> uploadErrors,
131 AnalyzedZipHeatFiles analyzedZipHeatFiles)
133 FilesDataStructure structure = new FilesDataStructure();
134 Set<String> usedEnvFiles = new HashSet<>();
135 addHeatsToFileDataStructure(tree, usedEnvFiles, structure, uploadErrors,
136 analyzedZipHeatFiles);
137 handleOtherResources(tree, usedEnvFiles, structure);
138 FilesDataStructure fileDataStructureFromManifest =
139 createFileDataStructureFromManifest(zipContentMap.getFileContent
140 (SdcCommon.MANIFEST_NAME));
141 List<String> structureArtifacts = structure.getArtifacts();
142 structureArtifacts.addAll(fileDataStructureFromManifest.getArtifacts().stream().filter
143 (artifact -> !structureArtifacts.contains(artifact)).collect((Collectors.toList())));
144 handleArtifactsFromTree(tree, structure);
146 return JsonUtil.object2Json(structure);
150 public OrchestrationTemplateCandidateData createCandidateDataEntity(
151 CandidateDataEntityTo candidateDataEntityTo, InputStream zipFileManifest,
152 AnalyzedZipHeatFiles analyzedZipHeatFiles) throws Exception {
155 mdcDataDebugMessage.debugEntryMessage(null);
157 FileContentHandler zipContentMap = candidateDataEntityTo.getContentMap();
158 FilesDataStructure filesDataStructure;
159 String dataStructureJson;
161 if (zipFileManifest != null) {
162 // create data structure from manifest
163 filesDataStructure = createFileDataStructureFromManifest(zipFileManifest);
164 Set<String> zipFileList = zipContentMap.getFileList();
165 balanceManifestFilesWithZipFiles(filesDataStructure,
166 zipContentMap, analyzedZipHeatFiles);
167 Set<String> filesDataStructureFiles = getFlatFileNames(filesDataStructure);
168 filesDataStructure.getUnassigned().addAll(zipFileList.stream()
169 .filter(fileName -> (!filesDataStructureFiles.contains(fileName) &&
170 !filesDataStructure.getNested().contains(fileName) &&
171 !fileName.equals(SdcCommon.MANIFEST_NAME)))
172 .collect(Collectors.toList()));
173 dataStructureJson = JsonUtil.object2Json(filesDataStructure);
175 // create data structure from based on naming convention
177 heatStructureTreeToFileDataStructure(candidateDataEntityTo.getTree(), zipContentMap,
178 candidateDataEntityTo.getErrors(), analyzedZipHeatFiles);
181 mdcDataDebugMessage.debugExitMessage(null);
182 return new OrchestrationTemplateCandidateData(
183 ByteBuffer.wrap(candidateDataEntityTo.getUploadedFileData()), dataStructureJson);
186 private void balanceManifestFilesWithZipFiles(
187 FilesDataStructure filesDataStructure,
188 FileContentHandler fileContentHandler, AnalyzedZipHeatFiles analyzedZipHeatFiles)
190 Set<String> zipFileList = fileContentHandler.getFileList();
191 filesDataStructure.getNested().addAll(analyzedZipHeatFiles.getNestedFiles());
192 List<Module> modules = filesDataStructure.getModules();
193 if (CollectionUtils.isEmpty(modules)) {
197 for (int i = 0; i < modules.size(); i++) {
198 Module module = modules.get(i);
199 if (!isFileExistInZipContains(zipFileList, module.getYaml())) {
200 addFileToUnassigned(filesDataStructure, zipFileList, module.getEnv());
201 addFileToUnassigned(filesDataStructure, zipFileList, module.getVol());
202 addFileToUnassigned(filesDataStructure, zipFileList, module.getVolEnv());
204 } else if (Objects.nonNull(module.getVol()) && !zipFileList.contains(module.getVol())) {
207 .addIgnoreNull(filesDataStructure.getUnassigned(), module.getVolEnv());
209 if (filesDataStructure.getNested().contains(module.getYaml())) {
210 moveModuleFileToNested(filesDataStructure, i--, module);
216 private void addFileToUnassigned(FilesDataStructure filesDataStructure, Set<String> zipFileList,
218 if (isFileExistInZipContains(zipFileList, fileName)) {
219 filesDataStructure.getUnassigned().add(fileName);
223 private boolean isFileExistInZipContains(Set<String> zipFileList, String fileName) {
224 return Objects.nonNull(fileName) && zipFileList.contains(fileName);
227 private void moveModuleFileToNested(FilesDataStructure filesDataStructure, int i,
229 if (!filesDataStructure.getNested().contains(module.getYaml())) {
230 filesDataStructure.getNested().add(module.getYaml());
232 if (Objects.nonNull(module.getEnv())) {
233 filesDataStructure.getNested().add(module.getEnv());
235 if (Objects.nonNull(module.getVol())) {
236 filesDataStructure.getNested().add(module.getVol());
238 if (Objects.nonNull(module.getVolEnv())) {
239 filesDataStructure.getNested().add(module.getVolEnv());
241 filesDataStructure.getModules().remove(i);
244 private Set<String> getFlatFileNames(FilesDataStructure filesDataStructure) {
245 Set<String> fileNames = new HashSet<>();
246 if (!CollectionUtils.isEmpty(filesDataStructure.getModules())) {
247 for (Module module : filesDataStructure.getModules()) {
248 CollectionUtils.addIgnoreNull(fileNames, module.getEnv());
249 CollectionUtils.addIgnoreNull(fileNames, module.getVol());
250 CollectionUtils.addIgnoreNull(fileNames, module.getVolEnv());
251 CollectionUtils.addIgnoreNull(fileNames, module.getYaml());
254 fileNames.addAll(filesDataStructure.getArtifacts().stream().collect(Collectors.toSet()));
255 fileNames.addAll(filesDataStructure.getNested().stream().collect(Collectors.toSet()));
256 fileNames.addAll(filesDataStructure.getUnassigned().stream().collect(Collectors.toSet()));
261 private FilesDataStructure createFileDataStructureFromManifest(InputStream isManifestContent) {
264 mdcDataDebugMessage.debugEntryMessage(null);
266 ManifestContent manifestContent =
267 JsonUtil.json2Object(isManifestContent, ManifestContent.class);
268 FilesDataStructure structure = new FilesDataStructure();
269 for (FileData fileData : manifestContent.getData()) {
270 if (Objects.nonNull(fileData.getType()) &&
271 fileData.getType().equals(FileData.Type.HEAT)) {
272 Module module = new Module();
273 module.setYaml(fileData.getFile());
274 module.setIsBase(fileData.getBase());
275 addHeatDependenciesToModule(module, fileData.getData());
276 structure.getModules().add(module);
277 } else if (HeatFileAnalyzer.isYamlOrEnvFile(fileData.getFile()) &&
278 !FileData.Type.isArtifact(fileData.getType())) {
279 structure.getUnassigned().add(fileData.getFile());
281 structure.getArtifacts().add(fileData.getFile());
285 mdcDataDebugMessage.debugExitMessage(null);
289 private void addHeatDependenciesToModule(Module module, List<FileData> data) {
290 if (CollectionUtils.isEmpty(data)) {
294 for (FileData fileData : data) {
295 if (fileData.getType().equals(FileData.Type.HEAT_ENV)) {
296 module.setEnv(fileData.getFile());
297 } else if (fileData.getType().equals(FileData.Type.HEAT_VOL))// must be volume
299 module.setVol(fileData.getFile());
300 if (!CollectionUtils.isEmpty(fileData.getData())) {
301 FileData volEnv = fileData.getData().get(0);
302 if (volEnv.getType().equals(FileData.Type.HEAT_ENV)) {
303 module.setVolEnv(volEnv.getFile());
305 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
306 .withMessage(Messages.ILLEGAL_MANIFEST.getErrorMessage())
307 .withId(Messages.ILLEGAL_MANIFEST.getErrorMessage())
308 .withCategory(ErrorCategory.APPLICATION).build());
312 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
313 .withMessage(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
314 .withId(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
315 .withCategory(ErrorCategory.APPLICATION).build());
321 public void updateCandidateUploadData(OrchestrationTemplateCandidateData uploadData,
323 mdcDataDebugMessage.debugEntryMessage(null);
325 //vendorSoftwareProductDao.updateCandidateUploadData(uploadData);
326 orchestrationTemplateCandidateDataDao.update(itemId, uploadData);
328 mdcDataDebugMessage.debugExitMessage(null);
332 public Optional<FilesDataStructure> getOrchestrationTemplateCandidateFileDataStructure(
333 String vspId, Version version) {
335 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
337 Optional<String> jsonFileDataStructure =
338 orchestrationTemplateCandidateDataDao.getStructure(vspId, version);
340 if (jsonFileDataStructure.isPresent()) {
341 mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
343 .of(JsonUtil.json2Object(jsonFileDataStructure.get(), FilesDataStructure.class));
345 mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
346 return Optional.empty();
351 public void updateOrchestrationTemplateCandidateFileDataStructure(String vspId, Version version,
352 FilesDataStructure fileDataStructure) {
353 OrchestrationTemplateCandidateDaoFactory.getInstance().createInterface()
354 .updateStructure(vspId, version, fileDataStructure);
358 public OrchestrationTemplateCandidateData getOrchestrationTemplateCandidate(String vspId,
360 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
361 mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
363 return orchestrationTemplateCandidateDataDao.get(vspId, version);
367 public String createManifest(VspDetails vspDetails, FilesDataStructure structure) {
369 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
371 Optional<ManifestContent> manifest = manifestCreator.createManifest(vspDetails, structure);
372 if (!manifest.isPresent()) {
373 throw new RuntimeException(Messages.CREATE_MANIFEST_FROM_ZIP.getErrorMessage());
376 mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
377 return JsonUtil.object2Json(manifest.get());
381 public Optional<ManifestContent> createManifest(VspDetails vspDetails,
382 FileContentHandler fileContentHandler,
383 AnalyzedZipHeatFiles analyzedZipHeatFiles) {
386 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
388 mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
389 return manifestCreator.createManifest(vspDetails, fileContentHandler, analyzedZipHeatFiles);
393 public Optional<ByteArrayInputStream> fetchZipFileByteArrayInputStream(String vspId,
394 OrchestrationTemplateCandidateData candidateDataEntity,
396 Map<String, List<ErrorMessage>> uploadErrors) {
398 ByteArrayInputStream byteArrayInputStream = null;
400 file = replaceManifestInZip(candidateDataEntity.getContentData(), manifest, vspId);
401 byteArrayInputStream = new ByteArrayInputStream(
402 Objects.isNull(file) ? candidateDataEntity.getContentData().array()
404 } catch (IOException e) {
405 ErrorMessage errorMessage =
406 new ErrorMessage(ErrorLevel.ERROR,
407 Messages.CANDIDATE_PROCESS_FAILED.getErrorMessage());
408 logger.error(errorMessage.getMessage(), e);
410 .addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE, errorMessage, uploadErrors);
412 return Optional.ofNullable(byteArrayInputStream);
416 public byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, String vspId)
418 ByteArrayOutputStream baos = new ByteArrayOutputStream();
420 try (final ZipOutputStream zos = new ZipOutputStream(baos);
421 ZipInputStream zipStream = new ZipInputStream(
422 new ByteArrayInputStream(contentData.array()))) {
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];
431 while ((len = zipStream.read(buf)) > 0) {
432 zos.write(buf, 0, (len < buf.length) ? len : buf.length);
435 manifestWritten = true;
436 writeManifest(manifest, zos);
440 if (!manifestWritten) {
441 writeManifest(manifest, zos);
445 return baos.toByteArray();
449 public Optional<List<ErrorMessage>> validateFileDataStructure(
450 FilesDataStructure filesDataStructure) {
451 return candidateServiceValidator.validateFileDataStructure(filesDataStructure);
454 private void writeManifest(String manifest, ZipOutputStream zos) throws IOException {
455 zos.putNextEntry(new ZipEntry(SdcCommon.MANIFEST_NAME));
456 try (InputStream manifestStream = new ByteArrayInputStream(
457 manifest.getBytes(StandardCharsets.UTF_8))) {
458 byte[] buf = new byte[1024];
460 while ((len = (manifestStream.read(buf))) > 0) {
461 zos.write(buf, 0, (len < buf.length) ? len : buf.length);
466 private void handleArtifactsFromTree(HeatStructureTree tree, FilesDataStructure structure) {
468 if (Objects.isNull(tree) || Objects.isNull(tree.getArtifacts())) {
472 if (CollectionUtils.isNotEmpty(tree.getArtifacts())) {
473 structure.getArtifacts().addAll(
476 .map(Artifact::getFileName)
477 .filter(fileName -> !structure.getArtifacts().contains(fileName))
478 .collect(Collectors.toList()));
482 private void handleOtherResources(HeatStructureTree tree, Set<String> usedEnvFiles,
483 FilesDataStructure structure) {
484 Set<HeatStructureTree> others = tree.getOther();
485 if (Objects.isNull(others)) {
489 List<String> artifacts = new ArrayList<>();
490 List<String> unassigned = new ArrayList<>();
491 for (HeatStructureTree other : others) {
492 if (HeatFileAnalyzer.isYamlOrEnvFile(other.getFileName())) {
493 if (isEnvFileUsedByHeatFile(usedEnvFiles, other)) {
496 unassigned.add(other.getFileName());
498 artifacts.add(other.getFileName());
500 handleArtifactsFromTree(other, structure);
502 structure.getArtifacts().addAll(artifacts);
503 structure.getUnassigned().addAll(unassigned);
506 private boolean isEnvFileUsedByHeatFile(Set<String> usedEnvFiles, HeatStructureTree other) {
507 if (HeatFileAnalyzer.isEnvFile(other.getFileName())) {
508 if (usedEnvFiles.contains(other.getFileName())) {
515 private void addHeatsToFileDataStructure(HeatStructureTree tree, Set<String> usedEnvFiles,
516 FilesDataStructure structure,
517 Map<String, List<ErrorMessage>> uploadErrors,
518 AnalyzedZipHeatFiles analyzedZipHeatFiles)
520 List<Module> modules = new ArrayList<>();
521 Set<HeatStructureTree> heatsSet = tree.getHeat();
522 if (Objects.isNull(heatsSet)) {
525 for (HeatStructureTree heat : heatsSet) {
526 if (isFileBaseFile(heat.getFileName())) {
527 handleSingleHeat(structure, modules, heat, uploadErrors);
528 } else if (isFileModuleFile(heat.getFileName(),
529 analyzedZipHeatFiles.getModuleFiles())) {
530 handleSingleHeat(structure, modules, heat, uploadErrors);
532 structure.getUnassigned().add(heat.getFileName());
533 addNestedToFileDataStructure(heat, structure);
535 if (!Objects.isNull(heat.getEnv())) {
536 usedEnvFiles.add(heat.getEnv() == null ? null : heat.getEnv().getFileName());
539 structure.setModules(modules);
543 private boolean isFileModuleFile(String fileName, Set<String> modulesFileNames) {
544 return modulesFileNames.contains(fileName);
547 private boolean isFileBaseFile(String fileName) {
548 return manifestCreator.isFileBaseFile(fileName);
551 private void handleSingleHeat(FilesDataStructure structure, List<Module> modules,
552 HeatStructureTree heat,
553 Map<String, List<ErrorMessage>> uploadErrors) {
556 mdcDataDebugMessage.debugEntryMessage(null);
558 Module module = new Module();
559 module.setYaml(heat.getFileName());
560 module.setIsBase(heat.getBase());
561 addNestedToFileDataStructure(heat, structure);
562 Set<HeatStructureTree> volumeSet = heat.getVolume();
564 if (Objects.nonNull(volumeSet)) {
565 handleVolumes(module, volumeSet, structure, inx, uploadErrors);
567 handleEnv(module, heat, false, structure);
570 mdcDataDebugMessage.debugExitMessage(null);
573 private void handleVolumes(Module module, Set<HeatStructureTree> volumeSet,
574 FilesDataStructure structure, int inx,
575 Map<String, List<ErrorMessage>> uploadErrors) {
578 mdcDataDebugMessage.debugEntryMessage(null);
580 for (HeatStructureTree volume : volumeSet) {
582 ErrorsUtil.addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE,
583 new ErrorMessage(ErrorLevel.WARNING,
584 Messages.MORE_THEN_ONE_VOL_FOR_HEAT.getErrorMessage()), uploadErrors);
587 handleArtifactsFromTree(volume, structure);
588 module.setVol(volume.getFileName());
589 handleEnv(module, volume, true, structure);
592 mdcDataDebugMessage.debugExitMessage(null);
595 private void handleEnv(Module module, HeatStructureTree tree, boolean isVolEnv,
596 FilesDataStructure structure) {
599 mdcDataDebugMessage.debugEntryMessage(null);
601 if (Objects.nonNull(tree.getEnv())) {
603 module.setVolEnv(tree.getEnv().getFileName());
605 module.setEnv(tree.getEnv().getFileName());
607 handleArtifactsFromTree(tree.getEnv(), structure);
610 mdcDataDebugMessage.debugExitMessage(null);
613 private void addNestedToFileDataStructure(HeatStructureTree heat,
614 FilesDataStructure structure) {
615 Set<HeatStructureTree> nestedSet = heat.getNested();
616 if (Objects.isNull(nestedSet)) {
619 for (HeatStructureTree nested : nestedSet) {
620 if (structure.getNested().contains(nested.getFileName())) {
623 structure.getNested().add(nested.getFileName());
624 if (CollectionUtils.isNotEmpty(nested.getArtifacts())) {
625 handleArtifactsFromTree(nested, structure);
627 addNestedToFileDataStructure(nested, structure);