From d37d9e6adead6a6568aafb2ac831237de32fbdca Mon Sep 17 00:00:00 2001 From: vasraz Date: Tue, 3 Oct 2023 14:55:02 +0100 Subject: Fix 'missing properties after service import'-bug Signed-off-by: Vasyl Razinkov Change-Id: Id8fa4c7d57e023a7e676a455bf5fae65cc6b9cf1 Issue-ID: SDC-4643 --- .../sdc/be/tosca/CommonCsarGenerator.java | 86 +++++++++++++++++++--- .../openecomp/sdc/be/tosca/ToscaExportHandler.java | 18 +++-- .../sdc/be/tosca/ToscaRepresentation.java | 3 +- 3 files changed, 86 insertions(+), 21 deletions(-) (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CommonCsarGenerator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CommonCsarGenerator.java index 16df325b24..677be6056d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CommonCsarGenerator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CommonCsarGenerator.java @@ -77,6 +77,7 @@ import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; import org.openecomp.sdc.be.dao.cassandra.SdcSchemaFilesCassandraDao; import org.openecomp.sdc.be.data.model.ToscaImportByModel; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; @@ -110,6 +111,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.DumperOptions.FlowStyle; import org.yaml.snakeyaml.Yaml; /** @@ -240,7 +242,8 @@ public class CommonCsarGenerator { addSchemaFilesFromCassandra(zip, schemaFileZip, nodesFromPackage, definitionsPath); } else { //retrieve schema files by model from Cassandra - addSchemaFilesByModel(zip, component.getModel(), definitionsPath, addDependencies); + addSchemaFilesByModel(zip, component.getModel(), definitionsPath, addDependencies, + dependencies.stream().map(d -> d.getRight()).collect(Collectors.toList())); } Either collectedComponentCsarDefinition = collectComponentCsarDefinition(component); if (collectedComponentCsarDefinition.isRight()) { @@ -396,8 +399,7 @@ public class CommonCsarGenerator { for (Triple d : dependencies) { String cassandraId = d.getMiddle(); Component childComponent = d.getRight(); - Either entryData = getEntryData(cassandraId, childComponent).right() - .map(componentsUtils::getResponseFormat); + Either entryData = getEntryData(cassandraId, childComponent).right().map(componentsUtils::getResponseFormat); if (entryData.isRight()) { return Either.right(entryData.right().value()); } @@ -548,9 +550,9 @@ public class CommonCsarGenerator { final String definitionsPath) { final int initSize = 2048; LOGGER.debug("Starting copy from Schema file zip to CSAR zip"); - try (final ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream( - schemaFileZip)); final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( - byteArrayOutputStream, initSize)) { + try (final ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream, initSize)) { ZipEntry entry; while ((entry = zipInputStream.getNextEntry()) != null) { ZipUtils.checkForZipSlipInRead(entry); @@ -652,12 +654,13 @@ public class CommonCsarGenerator { } private void addSchemaFilesByModel(final ZipOutputStream zipOutputStream, final String modelName, - final String definitionsPath, final boolean isSingleImportsFile) { + final String definitionsPath, final boolean isSingleImportsFile, + final List dependencies) { try { - final List modelDefaultImportList = modelOperation.findAllModelImports(modelName, true); final Set writtenEntryPathList = new HashSet<>(); - final var defsPath = Path.of(definitionsPath); - Map contentToMerge = new HashMap<>(); + final Path defsPath = Path.of(definitionsPath); + final Map contentToMerge = new HashMap<>(); + final List modelDefaultImportList = modelOperation.findAllModelImports(modelName, true); for (final ToscaImportByModel toscaImportByModel : modelDefaultImportList) { var importPath = Path.of(toscaImportByModel.getFullPath()); if (!isSingleImportsFile) { @@ -694,6 +697,7 @@ public class CommonCsarGenerator { zipOutputStream.putNextEntry(zipEntry); writtenEntryPathList.add(entry.getKey()); mergingContent = mergeContent(mergingContent, entry.getValue()); + mergingContent = updateMergingContentFromDependencies(mergingContent, dependencies); zipOutputStream.write(mergingContent, 0, mergingContent.length); zipOutputStream.closeEntry(); } @@ -706,13 +710,72 @@ public class CommonCsarGenerator { } } + private byte[] updateMergingContentFromDependencies(final byte[] mergingContent, final List dependencies) { + final DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(FlowStyle.BLOCK); + final Yaml yaml = new Yaml(options); + final Map stringObjectMap = (Map) yaml.load(new String(mergingContent)); + final Map nodeTypes = (Map) stringObjectMap.get("node_types"); + for (final Component dependency : dependencies) { + final Map dependencyAsMap = yaml.load(yaml.dumpAsMap(dependency)); + final String toscaResourceName = ((ResourceMetadataDataDefinition) dependency.getComponentMetadataDefinition() + .getMetadataDataDefinition()).getToscaResourceName(); + final Map nodeType = (Map) nodeTypes.get(toscaResourceName); + final Map propertiesFromDependency = (Map) ((List) dependencyAsMap.get("properties")) + .stream().collect(Collectors.toMap(s -> ((Map) s).get("name"), s -> s)); + if (MapUtils.isNotEmpty(nodeType) && MapUtils.isNotEmpty(propertiesFromDependency)) { + final Map propertiesFromMergingContent = (Map) nodeType.get("properties"); + final Map updatedMap = updatePropertiesFromDependency(propertiesFromMergingContent, propertiesFromDependency); + nodeType.replace("properties", updatedMap); + nodeTypes.replace(toscaResourceName, nodeType); + } + } + stringObjectMap.replace("node_types", nodeTypes); + return yaml.dumpAsMap(stringObjectMap).getBytes(); + } + + private Map updatePropertiesFromDependency(final Map propertiesFromMergingContent, + final Map propertiesFromDependency) { + final Map result = new HashMap<>(); + for (final Entry entry : propertiesFromDependency.entrySet()) { + final Map propertiesMap = new HashMap<>(); + final String key = entry.getKey(); + final Object value = entry.getValue(); + if (propertiesFromMergingContent instanceof Map) { + final Object object = propertiesFromMergingContent.get(key); + if (object instanceof Map) { + ((Map) object).keySet().forEach(s -> + propertiesMap.put(s, ((Map) value).get(s)) + ); + } else { + propertiesMap.putAll(createProperties(value)); + } + } else { + propertiesMap.putAll(createProperties(value)); + } + result.put(key, propertiesMap); + } + return result; + } + + private Map createProperties(final Object value) { + final Map propertiesMap = new HashMap<>(); + propertiesMap.put("type", ((Map) value).get("type")); + propertiesMap.put("required", ((Map) value).get("required")); + final Object entrySchema = ((Map) value).get("entry_schema"); + if (entrySchema != null) { + propertiesMap.put("entry_schema", entrySchema); + } + return propertiesMap; + } + private byte[] mergeContent(final byte[] first, final byte[] second) { byte[] merged = new byte[0]; final Map firstMap = new Yaml().load(new String(first)); final Map secondMap = new Yaml().load(new String(second)); if (MapUtils.isNotEmpty(secondMap)) { final DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setDefaultFlowStyle(FlowStyle.BLOCK); final Yaml yaml = new Yaml(options); for (final Entry secondMapEntry : secondMap.entrySet()) { final Map newMap = new HashMap<>(); @@ -1271,4 +1334,5 @@ public class CommonCsarGenerator { } } + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 8c802bc43e..163b67a44f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -795,7 +795,7 @@ public class ToscaExportHandler { private void addDependencies(final List>> imports, final List> dependencies, final Component fetchedComponent, final boolean isSkipImports) { final Set componentsList = new LinkedHashSet<>(); - if (fetchedComponent instanceof Resource && !isSkipImports) { + if (fetchedComponent instanceof Resource) { log.debug("fetchedComponent is a resource {}", fetchedComponent); final Optional> derivedFromMapOfIdToName = getDerivedFromMapOfIdToName(fetchedComponent, componentsList); if (derivedFromMapOfIdToName.isPresent() && !derivedFromMapOfIdToName.get().isEmpty()) { @@ -808,9 +808,9 @@ public class ToscaExportHandler { } } }); - setImports(imports, dependencies, componentsList); + setImports(imports, dependencies, componentsList, isSkipImports); } else { - setImports(imports, dependencies, fetchedComponent); + setImports(imports, dependencies, fetchedComponent, isSkipImports); } } } @@ -844,12 +844,12 @@ public class ToscaExportHandler { * Creates a resource map and adds it to the import list. */ private void setImports(final List>> imports, final List> dependencies, - final Set componentsList) { - componentsList.forEach(component -> setImports(imports, dependencies, component)); + final Set componentsList, boolean isSkipImports) { + componentsList.forEach(component -> setImports(imports, dependencies, component, isSkipImports)); } private void setImports(final List>> imports, final List> dependencies, - final Component component) { + final Component component, boolean isSkipImports) { final Map toscaArtifacts = component.getToscaArtifacts(); final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); if (artifactDefinition != null) { @@ -860,9 +860,11 @@ public class ToscaExportHandler { keyNameBuilder.append(component.getComponentType().toString().toLowerCase()); keyNameBuilder.append("-"); keyNameBuilder.append(component.getName()); - addImports(imports, keyNameBuilder, files); + if (!isSkipImports) { + addImports(imports, keyNameBuilder, files); + } dependencies.add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component)); - if (!ModelConverter.isAtomicComponent(component)) { + if (!ModelConverter.isAtomicComponent(component) && !isSkipImports) { final Map interfaceFiles = new HashMap<>(); interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactName)); keyNameBuilder.append("-interface"); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java index 07463f83e4..8713be97fd 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java @@ -26,11 +26,10 @@ import org.apache.commons.lang3.tuple.Triple; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; +@Getter public class ToscaRepresentation { - @Getter private final byte[] mainYaml; - @Getter private final Option>> dependencies; private ToscaRepresentation(byte[] mainYaml, Option>> dependencies) { -- cgit 1.2.3-korg