From 9f7430db214092bba954fa07fd3e72e333116cfa Mon Sep 17 00:00:00 2001 From: aribeiro Date: Tue, 5 May 2020 14:36:38 +0100 Subject: Allow global types generation This change allows to configure which global type file will be added to the generated CSAR Issue-ID: SDC-3021 Change-Id: I83c0c3f317c4a4e5e8dbf22cb3dbd47e63562d3a Signed-off-by: aribeiro --- .../templates/default/BE-configuration.yaml.erb | 12 +++ .../java/org/openecomp/sdc/be/tosca/CsarUtils.java | 57 +++++++---- .../openecomp/sdc/be/tosca/ToscaExportHandler.java | 1 - .../src/main/resources/config/configuration.yaml | 12 +++ .../org/openecomp/sdc/be/tosca/CsarUtilsTest.java | 57 ++++++++--- .../resources/config/catalog-be/configuration.yaml | 12 +++ .../yamlValidation/resource-serviceTemplate.yml | 105 +++++++++++++++++++++ .../org/openecomp/sdc/be/config/Configuration.java | 9 ++ 8 files changed, 234 insertions(+), 31 deletions(-) create mode 100644 catalog-be/src/test/resources/yamlValidation/resource-serviceTemplate.yml diff --git a/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb b/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb index a86378e9e0..a8ebf0656b 100644 --- a/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb +++ b/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb @@ -64,6 +64,18 @@ defaultImports: - annotations: file: annotations.yml +# Global CSAR Import Files +globalCsarImports: + - annotations.yml + - artifacts.yml + - capabilities.yml + - data.yml + - groups.yml + - interfaces.yml + - nodes.yml + - policies.yml + - relationships.yml + # Users users: tom: passwd diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java index 492ebcf0e4..478cf28d2e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java @@ -115,6 +115,7 @@ public class CsarUtils { private static final Logger log = Logger.getLogger(CsarUtils.class); private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(CsarUtils.class.getName()); private static final String PATH_DELIMITER = "/"; + public static final String NODES_YML = "nodes.yml"; @Autowired private SdcSchemaFilesCassandraDao sdcSchemaFilesCassandraDao; @Autowired @@ -129,6 +130,8 @@ public class CsarUtils { @Autowired(required = false) private List generators; + private static final List globalCsarImports = ConfigurationManager.getConfigurationManager() + .getConfiguration().getGlobalCsarImports(); private static final String CONFORMANCE_LEVEL = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel(); private static final String SDC_VERSION = ExternalConfiguration.getAppVersion(); public static final String ARTIFACTS_PATH = "Artifacts/"; @@ -537,34 +540,45 @@ public class CsarUtils { }).left().map(content -> new Tuple2<>(content, new ZipEntry(DEFINITIONS_PATH + fileName))); } - private void addSchemaFilesFromCassandra(final ZipOutputStream zip, + /** + * Writes to a CSAR zip from casandra schema data + * + * @param zipOutputStream stores the input stream content + * @param schemaFileZip zip data from Cassandra + * @param nodesFromPackage list of all nodes found on the onboarded package + * @param isHeatPackage true if the onboardead package is a Heat package + */ + private void addSchemaFilesFromCassandra(final ZipOutputStream zipOutputStream, final byte[] schemaFileZip, final List nodesFromPackage) { final int initSize = 2048; log.debug("Starting copy from Schema file zip to CSAR zip"); - try (final ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final BufferedOutputStream bos = new BufferedOutputStream(out, 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 = zipStream.getNextEntry()) != null) { + while ((entry = zipInputStream.getNextEntry()) != null) { ZipUtils.checkForZipSlipInRead(entry); final String entryName = entry.getName(); int readSize = initSize; final byte[] entryData = new byte[initSize]; - if (entryName.equalsIgnoreCase("nodes.yml")) { - handleNode(zipStream, out, nodesFromPackage); - } else { - while ((readSize = zipStream.read(entryData, 0, readSize)) != -1) { - bos.write(entryData, 0, readSize); + if (shouldZipEntryBeHandled(entryName)) { + if (NODES_YML.equalsIgnoreCase(entryName)) { + handleNode(zipInputStream, byteArrayOutputStream, nodesFromPackage); + } else { + while ((readSize = zipInputStream.read(entryData, 0, readSize)) != -1) { + bufferedOutputStream.write(entryData, 0, readSize); + } + bufferedOutputStream.flush(); } - bos.flush(); + byteArrayOutputStream.flush(); + zipOutputStream.putNextEntry(new ZipEntry(DEFINITIONS_PATH + entryName)); + zipOutputStream.write(byteArrayOutputStream.toByteArray()); + zipOutputStream.flush(); + byteArrayOutputStream.reset(); } - out.flush(); - zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + entryName)); - zip.write(out.toByteArray()); - zip.flush(); - out.reset(); } } catch (final Exception e) { log.error("Error while writing the SDC schema file to the CSAR", e); @@ -573,6 +587,17 @@ public class CsarUtils { log.debug("Finished copy from Schema file zip to CSAR zip"); } + /** + * Checks if the zip entry should or should not be added to the CSAR based on the given global type list + * + * @param entryName the zip entry name + * @return true if the zip entry should be handled + */ + private boolean shouldZipEntryBeHandled(final String entryName) { + return globalCsarImports.stream() + .anyMatch(entry -> entry.contains(entryName)); + } + /** * Handles the nodes.yml zip entry, updating the nodes.yml to avoid duplicated nodes on it. * 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 1ca087d38a..0a51e5901b 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 @@ -249,7 +249,6 @@ public class ToscaExportHandler { log.debug(FAILED_TO_GET_DEFAULT_IMPORTS_CONFIGURATION); return Either.right(ToscaError.GENERAL_ERROR); } - log.trace("start tosca export for {}", component.getUniqueId()); String toscaVersion = null; if (component instanceof Resource) { diff --git a/catalog-be/src/main/resources/config/configuration.yaml b/catalog-be/src/main/resources/config/configuration.yaml index b56c243093..3e34e2176f 100644 --- a/catalog-be/src/main/resources/config/configuration.yaml +++ b/catalog-be/src/main/resources/config/configuration.yaml @@ -91,6 +91,18 @@ defaultImports: - annotations: file: annotations.yml +# Global CSAR Import Files +globalCsarImports: + - annotations.yml + - artifacts.yml + - capabilities.yml + - data.yml + - groups.yml + - interfaces.yml + - nodes.yml + - policies.yml + - relationships.yml + # Users users: tom: passwd diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java index 4fd8a70229..8f1e9f9199 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/CsarUtilsTest.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -29,8 +29,11 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import fj.data.Either; +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -41,14 +44,14 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import mockit.Deencapsulation; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutableTriple; @@ -63,6 +66,7 @@ import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.components.BeConfDependentTest; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; @@ -85,7 +89,9 @@ import org.openecomp.sdc.be.tosca.CsarUtils.NonMetaArtifactInfo; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.ConfigurationSource; import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.exception.ResponseFormat; public class CsarUtilsTest extends BeConfDependentTest { @@ -111,15 +117,31 @@ public class CsarUtilsTest extends BeConfDependentTest { @Mock private ArtifactsBusinessLogic artifactsBusinessLogic; + public CsarUtilsTest() throws IOException { + } + @Before public void setUpMock() throws Exception { ExternalConfiguration.setAppName("catalog-be"); MockitoAnnotations.initMocks(this); - + initConfigurationManager(); + } + + private static void initConfigurationManager() { + final String confPath = new File(Objects + .requireNonNull( + CsarUtilsTest.class.getClassLoader().getResource("config/catalog-be/configuration.yaml")) + .getFile()).getParent(); + final ConfigurationSource confSource = + new FSConfigurationSource(ExternalConfiguration.getChangeListener(), confPath); + new ConfigurationManager(confSource); } private final List nodesFromPackage = Arrays.asList("tosca.nodes.Root", "tosca.nodes.Container.Application"); + private final byte[] contentData = getFileResource("yamlValidation/resource-serviceTemplate.yml"); + + private NonMetaArtifactInfo createNonMetaArtifactInfoTestSubject() { return new CsarUtils.NonMetaArtifactInfo("mock", "mock", ArtifactTypeEnum.AAI_SERVICE_MODEL.getType(), ArtifactGroupTypeEnum.DEPLOYMENT, new byte[0], "mock", true); @@ -283,13 +305,12 @@ public class CsarUtilsTest extends BeConfDependentTest { component.setLastUpdaterUserId("userId"); component.setUniqueId("uid"); DAOArtifactData artifactData = new DAOArtifactData(); - byte[] data = "value".getBytes(); - ByteBuffer bufferData = ByteBuffer.wrap(data); + ByteBuffer bufferData = ByteBuffer.wrap(contentData); artifactData.setData(bufferData); List filesData = new ArrayList<>(); SdcSchemaFilesData filedata = new SdcSchemaFilesData(); - filedata.setPayloadAsArray(data); + filedata.setPayloadAsArray(contentData); filesData.add(filedata); ToscaTemplate toscaTemplate = new ToscaTemplate("version"); @@ -405,8 +426,7 @@ public class CsarUtilsTest extends BeConfDependentTest { component.setLastUpdaterUserId("userId"); component.setUniqueId("uid"); DAOArtifactData artifactData = new DAOArtifactData(); - byte[] data = "value".getBytes(); - ByteBuffer bufferData = ByteBuffer.wrap(data); + ByteBuffer bufferData = ByteBuffer.wrap(contentData); artifactData.setData(bufferData); ToscaTemplate toscaTemplate = new ToscaTemplate("version"); @@ -416,7 +436,7 @@ public class CsarUtilsTest extends BeConfDependentTest { toscaTemplate.setDependencies(dependencies); ToscaRepresentation tosca = new ToscaRepresentation(); - tosca.setMainYaml("value"); + tosca.setMainYaml(new String(contentData, StandardCharsets.UTF_8)); Mockito.when(artifactCassandraDao.getArtifact(Mockito.any(String.class))).thenReturn(Either.left(artifactData)); @@ -457,8 +477,7 @@ public class CsarUtilsTest extends BeConfDependentTest { component.setLastUpdaterUserId("userId"); component.setUniqueId("uid"); DAOArtifactData artifactData = new DAOArtifactData(); - byte[] data = "value".getBytes(); - ByteBuffer bufferData = ByteBuffer.wrap(data); + ByteBuffer bufferData = ByteBuffer.wrap(contentData); artifactData.setData(bufferData); ToscaTemplate toscaTemplate = new ToscaTemplate("version"); @@ -468,7 +487,7 @@ public class CsarUtilsTest extends BeConfDependentTest { toscaTemplate.setDependencies(dependencies); ToscaRepresentation tosca = new ToscaRepresentation(); - tosca.setMainYaml("value"); + tosca.setMainYaml(new String(contentData, StandardCharsets.UTF_8)); Mockito.when(artifactCassandraDao.getArtifact(Mockito.any(String.class))).thenReturn(Either.left(artifactData)); @@ -970,4 +989,14 @@ public class CsarUtilsTest extends BeConfDependentTest { assertEquals(expectedResult, result); } + private byte[] getFileResource(final String filePath) throws IOException { + try (final InputStream inputStream = getFileResourceAsInputStream(filePath)) { + return IOUtils.toByteArray(inputStream); + } + } + + private InputStream getFileResourceAsInputStream(final String filePath) { + return Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath); + } + } diff --git a/catalog-be/src/test/resources/config/catalog-be/configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/configuration.yaml index ac5d0acc72..484206c39a 100644 --- a/catalog-be/src/test/resources/config/catalog-be/configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/configuration.yaml @@ -59,6 +59,18 @@ defaultImports: - policies: file: policies.yml +# Global CSAR Import Files +globalCsarImports: + - annotations.yml + - artifacts.yml + - capabilities.yml + - data.yml + - groups.yml + - interfaces.yml + - nodes.yml + - policies.yml + - relationships.yml + # Users users: tom: passwd diff --git a/catalog-be/src/test/resources/yamlValidation/resource-serviceTemplate.yml b/catalog-be/src/test/resources/yamlValidation/resource-serviceTemplate.yml new file mode 100644 index 0000000000..2928f0483b --- /dev/null +++ b/catalog-be/src/test/resources/yamlValidation/resource-serviceTemplate.yml @@ -0,0 +1,105 @@ +tosca_definitions_version: tosca_simple_yaml_1_1 +metadata: + invariantUUID: 10f015ca-e563-40ef-965e-79fe694695d1 + UUID: 7c7796a4-92b7-4e74-b75b-e54aa91665af + name: CinderVolume + description: 'Represents a server-local block storage device that provides persistent + storage to guest virtual machines. ' + type: VFC + category: Generic + subcategory: Infrastructure + resourceVendor: ONAP (Tosca) + resourceVendorRelease: 1.0.0.wd03 + resourceVendorModelNumber: '' +imports: +- nodes: + file: nodes.yml +- datatypes: + file: data.yml +- capabilities: + file: capabilities.yml +- relationships: + file: relationships.yml +- groups: + file: groups.yml +- policies: + file: policies.yml +node_types: + org.openecomp.resource.vfc.nodes.heat.cinder.Volume: + derived_from: org.openecomp.resource.vfc.nodes.volume + description: 'Represents a server-local block storage device that provides persistent + storage to guest virtual machines. ' + properties: + availability_zone: + type: string + description: The availability zone in which the volume will be created + required: false + image: + type: string + description: If specified, the name or ID of the image to create the volume from + required: false + metadata: + type: map + description: Key/value pairs to associate with the volume + required: false + entry_schema: + type: string + volume_type: + type: string + description: If specified, the type of volume to use, mapping to a specific backend + required: false + description: + type: string + description: A description of the volume + required: false + device_type: + type: string + description: Device type + required: false + disk_bus: + type: string + description: 'Bus of the device: hypervisor driver chooses a suitable default + if omitted' + required: false + backup_id: + type: string + description: If specified, the backup to create the volume from + required: false + source_volid: + type: string + description: If specified, the volume to use as source + required: false + boot_index: + type: integer + description: Integer used for ordering the boot disks + required: false + size: + type: scalar-unit.size + description: The requested storage size (default unit is MB) + required: false + read_only: + type: boolean + description: Enables or disables read-only access mode of volume + required: false + name: + type: string + description: A name used to distinguish the volume + required: false + scheduler_hints: + type: map + description: Arbitrary key-value pairs specified by the client to help the Cinder scheduler creating a volume + required: false + entry_schema: + type: string + swap_size: + type: scalar-unit.size + description: The size of the swap, in MB + required: false + delete_on_termination: + type: boolean + description: Indicate whether the volume should be deleted when the server is terminated + required: false + multiattach: + type: boolean + description: Whether allow the volume to be attached more than once + required: false diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java b/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java index b574f67644..b70a16193c 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java @@ -79,6 +79,7 @@ public class Configuration extends BasicConfiguration { private Long uebHealthCheckReadTimeout; private List>> defaultImports; + private List globalCsarImports; private List resourceTypes; private List excludeResourceCategory; private List excludeResourceType; @@ -1577,6 +1578,14 @@ public class Configuration extends BasicConfiguration { this.artifactsIndex = artifactsIndex; } + public List getGlobalCsarImports() { + return globalCsarImports; + } + + public void setGlobalCsarImports(List globalCsarImports) { + this.globalCsarImports = globalCsarImports; + } + public List getResourceTypes() { return resourceTypes; } -- cgit 1.2.3-korg