diff options
author | talig <talig@amdocs.com> | 2018-05-27 14:47:32 +0300 |
---|---|---|
committer | talig <talig@amdocs.com> | 2018-05-27 14:47:32 +0300 |
commit | fa2c7f888495ed0969ce9178b9f770ac088a5f07 (patch) | |
tree | f3b28e1bd6bbff6b5fc1ffb3ea4c4bda40788136 /openecomp-be/lib/openecomp-sdc-vendor-software-product-lib | |
parent | c42dd9b1b5659244d6306899cecd346dedfd32e1 (diff) |
Refactor candidate heat dao
As a result OrchestrationTemplateCandidate element will be added if not exists instead of failing.
Change-Id: I1a1c9afed65018ed01be65ff07dabe1c2081bea7
Issue-ID: SDC-1371
Signed-off-by: talig <talig@amdocs.com>
Diffstat (limited to 'openecomp-be/lib/openecomp-sdc-vendor-software-product-lib')
4 files changed, 98 insertions, 130 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/OrchestrationTemplateCandidateDao.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/OrchestrationTemplateCandidateDao.java index 9743814b11..c44ee307b4 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/OrchestrationTemplateCandidateDao.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/OrchestrationTemplateCandidateDao.java @@ -26,9 +26,9 @@ import java.util.Optional; public interface OrchestrationTemplateCandidateDao extends VersionableDao { - OrchestrationTemplateCandidateData get(String vspId, Version version); + Optional<OrchestrationTemplateCandidateData> get(String vspId, Version version); - OrchestrationTemplateCandidateData getInfo(String vspId, Version version); + Optional<OrchestrationTemplateCandidateData> getInfo(String vspId, Version version); void delete(String vspId, Version version); diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/filedatastructuremodule/CandidateService.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/filedatastructuremodule/CandidateService.java index 00120759d6..578b120256 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/filedatastructuremodule/CandidateService.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/filedatastructuremodule/CandidateService.java @@ -44,7 +44,7 @@ public interface CandidateService { OrchestrationTemplateCandidateData createCandidateDataEntity( CandidateDataEntityTo candidateDataEntityTo, InputStream zipFileManifest, - AnalyzedZipHeatFiles analyzedZipHeatFiles) throws Exception; + AnalyzedZipHeatFiles analyzedZipHeatFiles); void updateCandidateUploadData(String vspId, Version version, OrchestrationTemplateCandidateData uploadData); @@ -55,11 +55,11 @@ public interface CandidateService { void updateOrchestrationTemplateCandidateFileDataStructure(String vspId, Version version, FilesDataStructure fileDataStructure); - OrchestrationTemplateCandidateData getOrchestrationTemplateCandidate(String vspId, - Version version); + Optional<OrchestrationTemplateCandidateData> getOrchestrationTemplateCandidate(String vspId, + Version version); - OrchestrationTemplateCandidateData getOrchestrationTemplateCandidateInfo(String vspId, - Version version); + Optional<OrchestrationTemplateCandidateData> getOrchestrationTemplateCandidateInfo(String vspId, + Version version); byte[] getZipData(ByteBuffer contentData) throws IOException; @@ -71,7 +71,7 @@ public interface CandidateService { OnboardingTypesEnum type, Map<String, List<ErrorMessage>> uploadErrors); - byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, String vspId, + byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, OnboardingTypesEnum type) throws IOException; Optional<ManifestContent> createManifest(VspDetails vspDetails, diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java index 22fe1dd98c..f49832dc01 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/impl/zusammen/OrchestrationTemplateCandidateDaoZusammenImpl.java @@ -36,7 +36,6 @@ import org.openecomp.sdc.versioning.dao.types.Version; import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; -import java.util.Collection; import java.util.Optional; import static org.openecomp.core.zusammen.api.ZusammenUtil.buildStructuralElement; @@ -48,7 +47,7 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl private static final Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCandidateDaoZusammenImpl.class); - private ZusammenAdaptor zusammenAdaptor; + private final ZusammenAdaptor zusammenAdaptor; private static final String EMPTY_DATA = "{}"; @@ -62,8 +61,8 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl } @Override - public OrchestrationTemplateCandidateData get(String vspId, Version version) { - logger.info("Getting orchestration template for VendorSoftwareProduct id -> " + vspId); + public Optional<OrchestrationTemplateCandidateData> get(String vspId, Version version) { + logger.info("Getting orchestration template for vsp id {}", vspId); SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(vspId, version.getId()); @@ -71,93 +70,75 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl Optional<Element> candidateElement = zusammenAdaptor.getElementByName(context, elementContext, null, ElementType.OrchestrationTemplateCandidate.name()); - if (candidateElement.isPresent()) { - if (VspZusammenUtil.hasEmptyData(candidateElement.get().getData())) { - return null; - } - OrchestrationTemplateCandidateData candidateData = new OrchestrationTemplateCandidateData(); - candidateData.setFilesDataStructure( - new String(FileUtils.toByteArray(candidateElement.get().getData()))); - Collection<Element> subElements = candidateElement.get().getSubElements(); - if (subElements.isEmpty()) { - return candidateData; - } + if (!candidateElement.isPresent() || + VspZusammenUtil.hasEmptyData(candidateElement.get().getData()) || + candidateElement.get().getSubElements().isEmpty()) { + logger.info("Orchestration template for vsp id {} does not exist / has empty data", vspId); + return Optional.empty(); + } - for (Element element : subElements) { - Optional<Element> subElement = zusammenAdaptor.getElement(context, - elementContext, element.getElementId().toString()); - - if (subElement.get().getInfo().getName() - .equals(ElementType.OrchestrationTemplateCandidateContent - .name())) { - candidateData.setContentData( - ByteBuffer.wrap(FileUtils.toByteArray(subElement.get().getData()))); - candidateData.setFileSuffix(subElement.get().getInfo() - .getProperty(InfoPropertyName.FILE_SUFFIX.getVal())); - candidateData.setFileName(subElement.get().getInfo() - .getProperty(InfoPropertyName.FILE_NAME.getVal())); - } else if (subElement.get().getInfo().getName() - .equals(ElementType.OrchestrationTemplateCandidateValidationData.name())) { - candidateData.setValidationData(new String(FileUtils.toByteArray(subElement - .get().getData()))); - } - } + OrchestrationTemplateCandidateData candidate = new OrchestrationTemplateCandidateData(); + candidate.setFilesDataStructure( + new String(FileUtils.toByteArray(candidateElement.get().getData()))); - logger - .info("Finished getting orchestration template for VendorSoftwareProduct id -> " + vspId); - return candidateData; - } - logger.info(String - .format("Orchestration template for VendorSoftwareProduct id %s does not exist", vspId)); - return null; + candidateElement.get().getSubElements().stream() + .map(element -> zusammenAdaptor + .getElement(context, elementContext, element.getElementId().toString())) + .forEach(element -> element.ifPresent( + candidateInfoElement -> populateCandidate(candidate, candidateInfoElement, true))); + + logger.info("Finished getting orchestration template for vsp id {}", vspId); + return Optional.of(candidate); } @Override - public OrchestrationTemplateCandidateData getInfo(String vspId, Version version) { - logger.info("Getting orchestration template info for VendorSoftwareProduct id -> " + vspId); + public Optional<OrchestrationTemplateCandidateData> getInfo(String vspId, Version version) { + logger.info("Getting orchestration template info for vsp id {}", vspId); SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(vspId, version.getId()); - OrchestrationTemplateCandidateData candidateData = new OrchestrationTemplateCandidateData(); - Optional<ElementInfo> candidateElement = zusammenAdaptor.getElementInfoByName(context, elementContext, null, ElementType.OrchestrationTemplateCandidate.name()); - if (candidateElement.isPresent()) { - Collection<ElementInfo> subElements = candidateElement.get().getSubElements(); - if (subElements.isEmpty()) { - return candidateData; - } + if (!candidateElement.isPresent() || candidateElement.get().getSubElements().isEmpty()) { + logger.info("Orchestration template info for vsp id {} does not exist", vspId); + return Optional.empty(); + } - for (ElementInfo elementInfo : subElements) { - Optional<Element> subElement = zusammenAdaptor.getElement(context, - elementContext, elementInfo.getId().toString()); - - if (subElement.get().getInfo().getName().equals(ElementType - .OrchestrationTemplateCandidateContent.name())) { - - candidateData.setFileSuffix(subElement.get().getInfo() - .getProperty(InfoPropertyName.FILE_SUFFIX.getVal())); - candidateData.setFileName(subElement.get().getInfo() - .getProperty(InfoPropertyName.FILE_NAME.getVal())); - } else if (subElement.get().getInfo().getName().equals(ElementType - .OrchestrationTemplateCandidateValidationData.name())) { - candidateData.setValidationData(new String(FileUtils.toByteArray(subElement.get() - .getData()))); - } + OrchestrationTemplateCandidateData candidate = new OrchestrationTemplateCandidateData(); + candidateElement.get().getSubElements().stream() + .map(elementInfo -> zusammenAdaptor + .getElement(context, elementContext, elementInfo.getId().toString())) + .forEach(element -> element.ifPresent( + candidateInfoElement -> populateCandidate(candidate, candidateInfoElement, false))); + logger.info("Finished getting orchestration template info for vsp id {}", vspId); + return candidate.getFileSuffix() == null ? Optional.empty() : Optional.of(candidate); + } + + private void populateCandidate(OrchestrationTemplateCandidateData candidate, + Element candidateInfoElement, + boolean fullData) { + if (candidateInfoElement.getInfo().getName() + .equals(ElementType.OrchestrationTemplateCandidateContent.name())) { + + if (fullData) { + candidate + .setContentData(ByteBuffer.wrap(FileUtils.toByteArray(candidateInfoElement.getData()))); } + candidate.setFileSuffix( + candidateInfoElement.getInfo().getProperty(InfoPropertyName.FILE_SUFFIX.getVal())); + candidate.setFileName( + candidateInfoElement.getInfo().getProperty(InfoPropertyName.FILE_NAME.getVal())); + + } else if (candidateInfoElement.getInfo().getName() + .equals(ElementType.OrchestrationTemplateCandidateValidationData.name())) { - logger.info( - "Finished getting orchestration template info for VendorSoftwareProduct id -> " + vspId); - return candidateData; + candidate + .setValidationData(new String(FileUtils.toByteArray(candidateInfoElement.getData()))); } - logger.info(String - .format("Orchestration template info for VendorSoftwareProduct id %s does not exist", - vspId)); - return null; } @Override @@ -187,7 +168,7 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl @Override public void update(String vspId, Version version, OrchestrationTemplateCandidateData candidateData) { - logger.info("Uploading candidate data entity for VendorSoftwareProduct id -> " + vspId); + logger.info("Uploading candidate data entity for vsp id {}", vspId); ZusammenElement candidateElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidate, Action.UPDATE); @@ -215,15 +196,14 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl ElementContext elementContext = new ElementContext(vspId, version.getId()); zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate"); - logger - .info("Finished uploading candidate data entity for VendorSoftwareProduct id -> " + vspId); + logger.info("Finished uploading candidate data entity for vsp id {}", vspId); } @Override - public void updateValidationData(String vspId, Version version, ValidationStructureList - validationData) { - logger.info("Updating validation data of orchestration template candidate for VSP id -> " - + vspId); + public void updateValidationData(String vspId, Version version, + ValidationStructureList validationData) { + logger + .info("Updating validation data of orchestration template candidate for VSP id {} ", vspId); ZusammenElement validationDataElement = buildStructuralElement(ElementType .OrchestrationTemplateCandidateValidationData, Action.UPDATE); @@ -238,13 +218,14 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl ElementContext elementContext = new ElementContext(vspId, version.getId()); zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate validation data"); - logger.info("Finished updating validation data of orchestration template candidate for VSP " - + "id -> " + vspId); + logger + .info("Finished updating validation data of orchestration template candidate for VSP id {}", + vspId); } @Override public void updateStructure(String vspId, Version version, FilesDataStructure fileDataStructure) { - logger.info("Updating orchestration template for VSP id -> " + vspId); + logger.info("Updating orchestration template for VSP id {}", vspId); ZusammenElement candidateElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidate, Action.UPDATE); @@ -255,15 +236,13 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl ElementContext elementContext = new ElementContext(vspId, version.getId()); zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate structure"); - logger - .info("Finished uploading candidate data entity for VendorSoftwareProduct id -> " + vspId); + logger.info("Finished uploading candidate data entity for vsp id {}", vspId); } @Override public Optional<String> getStructure(String vspId, Version version) { - logger.info("Getting orchestration template candidate structure for VendorSoftwareProduct id " - + "-> " + vspId); + logger.info("Getting orchestration template candidate structure for vsp id {}", vspId); SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(vspId, version.getId()); @@ -275,9 +254,7 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl return Optional.of(new String(FileUtils.toByteArray(element.get().getData()))); } - logger.info( - "Finished getting orchestration template candidate structure for VendorSoftwareProduct " - + "id -> " + vspId); + logger.info("Finished getting orchestration template candidate structure for vsp id {}", vspId); return Optional.empty(); } @@ -286,13 +263,13 @@ public class OrchestrationTemplateCandidateDaoZusammenImpl FILE_SUFFIX("fileSuffix"), FILE_NAME("fileName"); - private String val; + private final String val; - InfoPropertyName(String val){ + InfoPropertyName(String val) { this.val = val; } - public String getVal() { + String getVal() { return val; } } diff --git a/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 b/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 index 4618d28756..43a94e03f0 100644 --- a/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 +++ b/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 @@ -70,7 +70,7 @@ import java.util.zip.ZipOutputStream; import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters; public class CandidateServiceImpl implements CandidateService { - protected static final Logger logger = LoggerFactory.getLogger(CandidateServiceImpl.class); + private static final Logger logger = LoggerFactory.getLogger(CandidateServiceImpl.class); private CandidateServiceValidator candidateServiceValidator = new CandidateServiceValidator(); private ManifestCreator manifestCreator; private OrchestrationTemplateCandidateDao orchestrationTemplateCandidateDao; @@ -79,7 +79,6 @@ public class CandidateServiceImpl implements CandidateService { OrchestrationTemplateCandidateDao orchestrationTemplateCandidateDao) { this.manifestCreator = manifestCreator; this.orchestrationTemplateCandidateDao = orchestrationTemplateCandidateDao; - } public CandidateServiceImpl() { @@ -125,8 +124,7 @@ public class CandidateServiceImpl implements CandidateService { private String heatStructureTreeToFileDataStructure(HeatStructureTree tree, FileContentHandler zipContentMap, Map<String, List<ErrorMessage>> uploadErrors, - AnalyzedZipHeatFiles analyzedZipHeatFiles) - throws Exception { + AnalyzedZipHeatFiles analyzedZipHeatFiles) { FilesDataStructure structure = new FilesDataStructure(); Set<String> usedEnvFiles = new HashSet<>(); addHeatsToFileDataStructure(tree, usedEnvFiles, structure, uploadErrors, @@ -150,7 +148,7 @@ public class CandidateServiceImpl implements CandidateService { @Override public OrchestrationTemplateCandidateData createCandidateDataEntity( CandidateDataEntityTo candidateDataEntityTo, InputStream zipFileManifest, - AnalyzedZipHeatFiles analyzedZipHeatFiles) throws Exception { + AnalyzedZipHeatFiles analyzedZipHeatFiles) { FileContentHandler zipContentMap = candidateDataEntityTo.getContentMap(); FilesDataStructure filesDataStructure; String dataStructureJson; @@ -183,8 +181,7 @@ public class CandidateServiceImpl implements CandidateService { private void balanceManifestFilesWithZipFiles( FilesDataStructure filesDataStructure, - FileContentHandler fileContentHandler, AnalyzedZipHeatFiles analyzedZipHeatFiles) - throws Exception { + FileContentHandler fileContentHandler, AnalyzedZipHeatFiles analyzedZipHeatFiles) { Set<String> zipFileList = fileContentHandler.getFileList(); filesDataStructure.getNested().addAll(analyzedZipHeatFiles.getNestedFiles()); List<Module> modules = filesDataStructure.getModules(); @@ -249,9 +246,9 @@ public class CandidateServiceImpl implements CandidateService { CollectionUtils.addIgnoreNull(fileNames, module.getYaml()); } } - fileNames.addAll(filesDataStructure.getArtifacts().stream().collect(Collectors.toSet())); - fileNames.addAll(filesDataStructure.getNested().stream().collect(Collectors.toSet())); - fileNames.addAll(filesDataStructure.getUnassigned().stream().collect(Collectors.toSet())); + fileNames.addAll(filesDataStructure.getArtifacts()); + fileNames.addAll(filesDataStructure.getNested()); + fileNames.addAll(filesDataStructure.getUnassigned()); return fileNames; } @@ -336,24 +333,23 @@ public class CandidateServiceImpl implements CandidateService { } @Override - public OrchestrationTemplateCandidateData getOrchestrationTemplateCandidate(String vspId, - Version version) { + public Optional<OrchestrationTemplateCandidateData> getOrchestrationTemplateCandidate(String vspId, + Version version) { return orchestrationTemplateCandidateDao.get(vspId, version); } @Override - public OrchestrationTemplateCandidateData getOrchestrationTemplateCandidateInfo(String vspId, - Version version) { + public Optional<OrchestrationTemplateCandidateData> getOrchestrationTemplateCandidateInfo( + String vspId, + Version version) { return orchestrationTemplateCandidateDao.getInfo(vspId, version); } @Override public String createManifest(VspDetails vspDetails, FilesDataStructure structure) { - Optional<ManifestContent> manifest = manifestCreator.createManifest(vspDetails, structure); - if (!manifest.isPresent()) { - throw new RuntimeException(Messages.CREATE_MANIFEST_FROM_ZIP.getErrorMessage()); - } - return JsonUtil.object2Json(manifest.get()); + return JsonUtil.object2Json(manifestCreator.createManifest(vspDetails, structure) + .orElseThrow(() -> new CoreException(new ErrorCode.ErrorCodeBuilder() + .withMessage(Messages.CREATE_MANIFEST_FROM_ZIP.getErrorMessage()).build()))); } @Override @@ -372,7 +368,7 @@ public class CandidateServiceImpl implements CandidateService { byte[] file; ByteArrayInputStream byteArrayInputStream = null; try { - file = replaceManifestInZip(candidateDataEntity.getContentData(), manifest, vspId, type); + file = replaceManifestInZip(candidateDataEntity.getContentData(), manifest, type); byteArrayInputStream = new ByteArrayInputStream( Objects.isNull(file) ? candidateDataEntity.getContentData().array() : file); @@ -388,7 +384,7 @@ public class CandidateServiceImpl implements CandidateService { } @Override - public byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, String vspId, + public byte[] replaceManifestInZip(ByteBuffer contentData, String manifest, OnboardingTypesEnum type) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -525,19 +521,14 @@ public class CandidateServiceImpl implements CandidateService { } private boolean isEnvFileUsedByHeatFile(Set<String> usedEnvFiles, HeatStructureTree other) { - if (HeatFileAnalyzer.isEnvFile(other.getFileName())) { - if (usedEnvFiles.contains(other.getFileName())) { - return true; - } - } - return false; + return HeatFileAnalyzer.isEnvFile(other.getFileName()) && + usedEnvFiles.contains(other.getFileName()); } private void addHeatsToFileDataStructure(HeatStructureTree tree, Set<String> usedEnvFiles, FilesDataStructure structure, Map<String, List<ErrorMessage>> uploadErrors, - AnalyzedZipHeatFiles analyzedZipHeatFiles) - throws Exception { + AnalyzedZipHeatFiles analyzedZipHeatFiles) { List<Module> modules = new ArrayList<>(); Set<HeatStructureTree> heatsSet = tree.getHeat(); if (Objects.isNull(heatsSet)) { |