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())) {
206 CollectionUtils.addIgnoreNull(filesDataStructure.getUnassigned(), module.getVolEnv());
208 if (filesDataStructure.getNested().contains(module.getYaml())) {
209 moveModuleFileToNested(filesDataStructure, i--, module);
215 private void addFileToUnassigned(FilesDataStructure filesDataStructure, Set<String> zipFileList,
217 if (isFileExistInZipContains(zipFileList, fileName)) {
218 filesDataStructure.getUnassigned().add(fileName);
222 private boolean isFileExistInZipContains(Set<String> zipFileList, String fileName) {
223 return Objects.nonNull(fileName) && zipFileList.contains(fileName);
226 private void moveModuleFileToNested(FilesDataStructure filesDataStructure, int i, Module module) {
227 if (!filesDataStructure.getNested().contains(module.getYaml())) {
228 filesDataStructure.getNested().add(module.getYaml());
230 if (Objects.nonNull(module.getEnv())) {
231 filesDataStructure.getNested().add(module.getEnv());
233 if (Objects.nonNull(module.getVol())) {
234 filesDataStructure.getNested().add(module.getVol());
236 if (Objects.nonNull(module.getVolEnv())) {
237 filesDataStructure.getNested().add(module.getVolEnv());
239 filesDataStructure.getModules().remove(i);
242 private Set<String> getFlatFileNames(FilesDataStructure filesDataStructure) {
243 Set<String> fileNames = new HashSet<>();
244 if (!CollectionUtils.isEmpty(filesDataStructure.getModules())) {
245 for (Module module : filesDataStructure.getModules()) {
246 CollectionUtils.addIgnoreNull(fileNames, module.getEnv());
247 CollectionUtils.addIgnoreNull(fileNames, module.getVol());
248 CollectionUtils.addIgnoreNull(fileNames, module.getVolEnv());
249 CollectionUtils.addIgnoreNull(fileNames, module.getYaml());
252 fileNames.addAll(filesDataStructure.getArtifacts().stream().collect(Collectors.toSet()));
253 fileNames.addAll(filesDataStructure.getNested().stream().collect(Collectors.toSet()));
254 fileNames.addAll(filesDataStructure.getUnassigned().stream().collect(Collectors.toSet()));
259 private FilesDataStructure createFileDataStructureFromManifest(InputStream isManifestContent) {
262 mdcDataDebugMessage.debugEntryMessage(null);
264 ManifestContent manifestContent =
265 JsonUtil.json2Object(isManifestContent, ManifestContent.class);
266 FilesDataStructure structure = new FilesDataStructure();
267 for (FileData fileData : manifestContent.getData()) {
268 if (Objects.nonNull(fileData.getType()) && fileData.getType().equals(FileData.Type.HEAT)) {
269 Module module = new Module();
270 module.setYaml(fileData.getFile());
271 module.setIsBase(fileData.getBase());
272 addHeatDependenciesToModule(module, fileData.getData());
273 structure.getModules().add(module);
274 } else if (HeatFileAnalyzer.isYamlOrEnvFile(fileData.getFile()) &&
275 !FileData.Type.isArtifact(fileData.getType())) {
276 structure.getUnassigned().add(fileData.getFile());
278 structure.getArtifacts().add(fileData.getFile());
282 mdcDataDebugMessage.debugExitMessage(null);
286 private void addHeatDependenciesToModule(Module module, List<FileData> data) {
287 if (CollectionUtils.isEmpty(data)) {
291 for (FileData fileData : data) {
292 if (fileData.getType().equals(FileData.Type.HEAT_ENV)) {
293 module.setEnv(fileData.getFile());
294 } else if (fileData.getType().equals(FileData.Type.HEAT_VOL))// must be volume
296 module.setVol(fileData.getFile());
297 if (!CollectionUtils.isEmpty(fileData.getData())) {
298 FileData volEnv = fileData.getData().get(0);
299 if (volEnv.getType().equals(FileData.Type.HEAT_ENV)) {
300 module.setVolEnv(volEnv.getFile());
302 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
303 .withMessage(Messages.ILLEGAL_MANIFEST.getErrorMessage())
304 .withId(Messages.ILLEGAL_MANIFEST.getErrorMessage())
305 .withCategory(ErrorCategory.APPLICATION).build());
309 throw new CoreException((new ErrorCode.ErrorCodeBuilder())
310 .withMessage(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
311 .withId(Messages.FILE_TYPE_NOT_LEGAL.getErrorMessage())
312 .withCategory(ErrorCategory.APPLICATION).build());
318 public void updateCandidateUploadData(OrchestrationTemplateCandidateData uploadData,
320 mdcDataDebugMessage.debugEntryMessage(null);
322 //vendorSoftwareProductDao.updateCandidateUploadData(uploadData);
323 orchestrationTemplateCandidateDataDao.update(itemId, uploadData);
325 mdcDataDebugMessage.debugExitMessage(null);
329 public Optional<FilesDataStructure> getOrchestrationTemplateCandidateFileDataStructure(
330 String vspId, Version version) {
332 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
334 Optional<String> jsonFileDataStructure =
335 orchestrationTemplateCandidateDataDao.getStructure(vspId, version);
337 if (jsonFileDataStructure.isPresent()) {
338 mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
340 .of(JsonUtil.json2Object(jsonFileDataStructure.get(), FilesDataStructure.class));
342 mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
343 return Optional.empty();
348 public void updateOrchestrationTemplateCandidateFileDataStructure(String vspId, Version version,
349 FilesDataStructure fileDataStructure) {
350 OrchestrationTemplateCandidateDaoFactory.getInstance().createInterface()
351 .updateStructure(vspId, version, fileDataStructure);
355 public OrchestrationTemplateCandidateData getOrchestrationTemplateCandidate(String vspId,
357 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspId);
358 mdcDataDebugMessage.debugExitMessage("VSP Id", vspId);
360 return orchestrationTemplateCandidateDataDao.get(vspId, version);
364 public String createManifest(VspDetails vspDetails, FilesDataStructure structure) {
366 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
368 Optional<ManifestContent> manifest = manifestCreator.createManifest(vspDetails, structure);
369 if (!manifest.isPresent()) {
370 throw new RuntimeException(Messages.CREATE_MANIFEST_FROM_ZIP.getErrorMessage());
373 mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
374 return JsonUtil.object2Json(manifest.get());
378 public Optional<ManifestContent> createManifest(VspDetails vspDetails,
379 FileContentHandler fileContentHandler,
380 AnalyzedZipHeatFiles analyzedZipHeatFiles) {
383 mdcDataDebugMessage.debugEntryMessage("VSP Id", vspDetails.getId());
385 mdcDataDebugMessage.debugExitMessage("VSP Id", vspDetails.getId());
386 return manifestCreator.createManifest(vspDetails, fileContentHandler, analyzedZipHeatFiles);
390 public Optional<ByteArrayInputStream> fetchZipFileByteArrayInputStream(String vspId,
391 OrchestrationTemplateCandidateData candidateDataEntity,
393 Map<String, List<ErrorMessage>> uploadErrors) {
395 ByteArrayInputStream byteArrayInputStream = null;
397 file = replaceManifestInZip(candidateDataEntity.getContentData(), manifest, vspId);
398 byteArrayInputStream = new ByteArrayInputStream(
399 Objects.isNull(file) ? candidateDataEntity.getContentData().array()
401 } catch (IOException e) {
402 ErrorMessage errorMessage =
403 new ErrorMessage(ErrorLevel.ERROR, Messages.CANDIDATE_PROCESS_FAILED.getErrorMessage());
404 logger.error(errorMessage.getMessage(), e);
405 ErrorsUtil.addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE, errorMessage, uploadErrors);
407 return Optional.ofNullable(byteArrayInputStream);
411 public byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, String vspId)
413 ByteArrayOutputStream baos = new ByteArrayOutputStream();
415 try (final ZipOutputStream zos = new ZipOutputStream(baos);
416 ZipInputStream zipStream = new ZipInputStream(
417 new ByteArrayInputStream(contentData.array()))) {
419 boolean manifestWritten = false;
420 while ((zipEntry = zipStream.getNextEntry()) != null) {
421 if (!zipEntry.getName().equalsIgnoreCase(SdcCommon.MANIFEST_NAME)) {
422 ZipEntry loc_ze = new ZipEntry(zipEntry.getName());
423 zos.putNextEntry(loc_ze);
424 byte[] buf = new byte[1024];
426 while ((len = zipStream.read(buf)) > 0) {
427 zos.write(buf, 0, (len < buf.length) ? len : buf.length);
430 manifestWritten = true;
431 writeManifest(manifest, zos);
435 if (!manifestWritten) {
436 writeManifest(manifest, zos);
440 return baos.toByteArray();
444 public Optional<List<ErrorMessage>> validateFileDataStructure(
445 FilesDataStructure filesDataStructure) {
446 return candidateServiceValidator.validateFileDataStructure(filesDataStructure);
449 private void writeManifest(String manifest, ZipOutputStream zos) throws IOException {
450 zos.putNextEntry(new ZipEntry(SdcCommon.MANIFEST_NAME));
451 try (InputStream manifestStream = new ByteArrayInputStream(
452 manifest.getBytes(StandardCharsets.UTF_8))) {
453 byte[] buf = new byte[1024];
455 while ((len = (manifestStream.read(buf))) > 0) {
456 zos.write(buf, 0, (len < buf.length) ? len : buf.length);
461 private void handleArtifactsFromTree(HeatStructureTree tree, FilesDataStructure structure) {
463 if (Objects.isNull(tree) || Objects.isNull(tree.getArtifacts())) {
467 if (CollectionUtils.isNotEmpty(tree.getArtifacts())) {
468 structure.getArtifacts().addAll(
471 .map(Artifact::getFileName)
472 .filter(fileName -> !structure.getArtifacts().contains(fileName))
473 .collect(Collectors.toList()));
477 private void handleOtherResources(HeatStructureTree tree, Set<String> usedEnvFiles,
478 FilesDataStructure structure) {
479 Set<HeatStructureTree> others = tree.getOther();
480 if (Objects.isNull(others)) {
484 List<String> artifacts = new ArrayList<>();
485 List<String> unassigned = new ArrayList<>();
486 for (HeatStructureTree other : others) {
487 if (HeatFileAnalyzer.isYamlOrEnvFile(other.getFileName())) {
488 if (isEnvFileUsedByHeatFile(usedEnvFiles, other)) {
491 unassigned.add(other.getFileName());
493 artifacts.add(other.getFileName());
495 handleArtifactsFromTree(other, structure);
497 structure.getArtifacts().addAll(artifacts);
498 structure.getUnassigned().addAll(unassigned);
501 private boolean isEnvFileUsedByHeatFile(Set<String> usedEnvFiles, HeatStructureTree other) {
502 if (HeatFileAnalyzer.isEnvFile(other.getFileName())) {
503 if (usedEnvFiles.contains(other.getFileName())) {
510 private void addHeatsToFileDataStructure(HeatStructureTree tree, Set<String> usedEnvFiles,
511 FilesDataStructure structure,
512 Map<String, List<ErrorMessage>> uploadErrors,
513 AnalyzedZipHeatFiles analyzedZipHeatFiles)
515 List<Module> modules = new ArrayList<>();
516 Set<HeatStructureTree> heatsSet = tree.getHeat();
517 if (Objects.isNull(heatsSet)) {
520 for (HeatStructureTree heat : heatsSet) {
521 if (isFileBaseFile(heat.getFileName())) {
522 handleSingleHeat(structure, modules, heat, uploadErrors);
523 } else if (isFileModuleFile(heat.getFileName(), analyzedZipHeatFiles.getModuleFiles())) {
524 handleSingleHeat(structure, modules, heat, uploadErrors);
526 structure.getUnassigned().add(heat.getFileName());
527 addNestedToFileDataStructure(heat, structure);
529 if (!Objects.isNull(heat.getEnv())) {
530 usedEnvFiles.add(heat.getEnv() == null ? null : heat.getEnv().getFileName());
533 structure.setModules(modules);
537 private boolean isFileModuleFile(String fileName, Set<String> modulesFileNames) {
538 return modulesFileNames.contains(fileName);
541 private boolean isFileBaseFile(String fileName) {
542 return manifestCreator.isFileBaseFile(fileName);
545 private void handleSingleHeat(FilesDataStructure structure, List<Module> modules,
546 HeatStructureTree heat,
547 Map<String, List<ErrorMessage>> uploadErrors) {
550 mdcDataDebugMessage.debugEntryMessage(null);
552 Module module = new Module();
553 module.setYaml(heat.getFileName());
554 module.setIsBase(heat.getBase());
555 addNestedToFileDataStructure(heat, structure);
556 Set<HeatStructureTree> volumeSet = heat.getVolume();
558 if (Objects.nonNull(volumeSet)) {
559 handleVolumes(module, volumeSet, structure, inx, uploadErrors);
561 handleEnv(module, heat, false, structure);
564 mdcDataDebugMessage.debugExitMessage(null);
567 private void handleVolumes(Module module, Set<HeatStructureTree> volumeSet,
568 FilesDataStructure structure, int inx,
569 Map<String, List<ErrorMessage>> uploadErrors) {
572 mdcDataDebugMessage.debugEntryMessage(null);
574 for (HeatStructureTree volume : volumeSet) {
576 ErrorsUtil.addStructureErrorToErrorMap(SdcCommon.UPLOAD_FILE,
577 new ErrorMessage(ErrorLevel.WARNING,
578 Messages.MORE_THEN_ONE_VOL_FOR_HEAT.getErrorMessage()), uploadErrors);
581 handleArtifactsFromTree(volume, structure);
582 module.setVol(volume.getFileName());
583 handleEnv(module, volume, true, structure);
586 mdcDataDebugMessage.debugExitMessage(null);
589 private void handleEnv(Module module, HeatStructureTree tree, boolean isVolEnv,
590 FilesDataStructure structure) {
593 mdcDataDebugMessage.debugEntryMessage(null);
595 if (Objects.nonNull(tree.getEnv())) {
597 module.setVolEnv(tree.getEnv().getFileName());
599 module.setEnv(tree.getEnv().getFileName());
601 handleArtifactsFromTree(tree.getEnv(), structure);
604 mdcDataDebugMessage.debugExitMessage(null);
607 private void addNestedToFileDataStructure(HeatStructureTree heat, FilesDataStructure structure) {
608 Set<HeatStructureTree> nestedSet = heat.getNested();
609 if (Objects.isNull(nestedSet)) {
612 for (HeatStructureTree nested : nestedSet) {
613 if (structure.getNested().contains(nested.getFileName())) {
616 structure.getNested().add(nested.getFileName());
617 if (CollectionUtils.isNotEmpty(nested.getArtifacts())) {
618 handleArtifactsFromTree(nested, structure);
620 addNestedToFileDataStructure(nested, structure);