diff options
author | andre.schmid <andre.schmid@est.tech> | 2019-08-30 18:20:32 +0100 |
---|---|---|
committer | Oren Kleks <orenkle@amdocs.com> | 2019-10-24 06:15:28 +0000 |
commit | 78f88751aa64fb72fd6321346929bd1d94f716a9 (patch) | |
tree | 58cabd13dcfbad357729ef338c8e2dca3255f1fb | |
parent | 105ce0729d5333cc095ef5bd8104a6c5b90cc9f0 (diff) |
Fix and refactor manifest parsing
Fix a CMS signature reading expected token.
Fix the necessity of a empty line in the end of the manifest.
Implement CMS signature, Source checksum algorithm and digest reading.
Indicate the line number and content when a manifest error occurs.
Remove unnecessary recursive reading.
Centralize manifest tokens.
Improve tests by checking the expected error.
Document the code.
Change-Id: I7d12020d8922fc5d4c8d9f238557dfbcc0b65757
Issue-ID: SDC-2563
Signed-off-by: andre.schmid <andre.schmid@est.tech>
44 files changed, 1536 insertions, 460 deletions
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilder.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilder.java index c7fd225c76..eff1fb31cd 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilder.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilder.java @@ -19,12 +19,17 @@ package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.ALGORITHM; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.HASH; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.METADATA; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.NON_MANO_ARTIFACT_SETS; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.SOURCE; + import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; -import org.openecomp.sdc.tosca.csar.CSARConstants; /** * Builds SOL0004 manifest file as a String. @@ -73,8 +78,8 @@ public class ManifestBuilder { */ public ManifestBuilder withSignedSource(final String sourcePath, final String hashAlgorithm, final String hash) { TreeMap<String, String> sourcePropertiesMap = new TreeMap<>(); - sourcePropertiesMap.put(CSARConstants.ALGORITHM_MF_ATTRIBUTE, hashAlgorithm); - sourcePropertiesMap.put(CSARConstants.HASH_MF_ATTRIBUTE, hash); + sourcePropertiesMap.put(ALGORITHM.getToken(), hashAlgorithm); + sourcePropertiesMap.put(HASH.getToken(), hash); sourceWithPropertiesMap.put(sourcePath, sourcePropertiesMap); return this; } @@ -119,7 +124,7 @@ public class ManifestBuilder { private String buildMetadata() { final StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(String.format(SECTION_FORMAT, CSARConstants.METADATA_MF_ATTRIBUTE)); + stringBuilder.append(String.format(SECTION_FORMAT, METADATA.getToken())); for (Entry<String, String> metadataAndValue : metadataMap.entrySet()) { stringBuilder.append("\t"); stringBuilder.append(String.format(PROPERTY_FORMAT, metadataAndValue.getKey(), metadataAndValue.getValue())); @@ -131,17 +136,17 @@ public class ManifestBuilder { private String buildSource() { final StringBuilder stringBuilder = new StringBuilder(); for (final Entry<String, Map<String, String>> signedSourceMap : sourceWithPropertiesMap.entrySet()) { - stringBuilder.append(String.format(PROPERTY_FORMAT, CSARConstants.SOURCE_MF_ATTRIBUTE, signedSourceMap.getKey())); + stringBuilder.append(String.format(PROPERTY_FORMAT, SOURCE.getToken(), signedSourceMap.getKey())); final Map<String, String> propertiesMap = signedSourceMap.getValue(); if (propertiesMap != null && !propertiesMap.isEmpty()) { - final String algorithm = propertiesMap.get(CSARConstants.ALGORITHM_MF_ATTRIBUTE); + final String algorithm = propertiesMap.get(ALGORITHM.getToken()); if (algorithm != null) { - stringBuilder.append(String.format(PROPERTY_FORMAT, CSARConstants.ALGORITHM_MF_ATTRIBUTE, algorithm)); + stringBuilder.append(String.format(PROPERTY_FORMAT, ALGORITHM.getToken(), algorithm)); } - final String hash = propertiesMap.get(CSARConstants.HASH_MF_ATTRIBUTE); + final String hash = propertiesMap.get(HASH.getToken()); if (hash != null) { - stringBuilder.append(String.format(PROPERTY_FORMAT, CSARConstants.HASH_MF_ATTRIBUTE, hash)); + stringBuilder.append(String.format(PROPERTY_FORMAT, HASH.getToken(), hash)); } } } @@ -151,13 +156,13 @@ public class ManifestBuilder { private String buildNonManoArtifact() { final StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(String.format(SECTION_FORMAT, CSARConstants.NON_MANO_MF_ATTRIBUTE)); + stringBuilder.append(String.format(SECTION_FORMAT, NON_MANO_ARTIFACT_SETS.getToken())); for (Entry<String, List<String>> artifactTypeAndSourcesEntry : nonManoArtifactMap.entrySet()) { stringBuilder.append("\t"); stringBuilder.append(String.format(SECTION_FORMAT, artifactTypeAndSourcesEntry.getKey())); for (String source : artifactTypeAndSourcesEntry.getValue()) { stringBuilder.append("\t\t"); - stringBuilder.append(String.format(PROPERTY_FORMAT, CSARConstants.SOURCE_MF_ATTRIBUTE, source)); + stringBuilder.append(String.format(PROPERTY_FORMAT, SOURCE.getToken(), source)); } } return stringBuilder.toString(); diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java index e022e2fedb..5079ecc0ac 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java @@ -24,6 +24,10 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_ARCHIVE_VERSION; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_NAME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_PROVIDER; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_RELEASE_DATE_TIME; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_PM_DICTIONARY; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_VES_EVENTS; @@ -34,7 +38,6 @@ import java.util.Map; import java.util.TreeMap; import org.junit.Before; import org.junit.Test; -import org.openecomp.sdc.tosca.csar.CSARConstants; import org.openecomp.sdc.tosca.csar.Manifest; import org.openecomp.sdc.tosca.csar.SOL004ManifestOnboarding; @@ -92,10 +95,10 @@ public class ManifestBuilderTest { @Test public void givenMetadata_whenBuildingManifestWithMetadata_thenParsedManifestMetadataShouldBeTheSame() { final Map<String, String> expectedMetadataMap = new TreeMap<>(); - expectedMetadataMap.put(CSARConstants.PNFD_NAME, "myPnf"); - expectedMetadataMap.put(CSARConstants.PNFD_PROVIDER, "Acme"); - expectedMetadataMap.put(CSARConstants.PNFD_ARCHIVE_VERSION, "1.0"); - expectedMetadataMap.put(CSARConstants.PNFD_RELEASE_DATE_TIME, "2019-03-11T11:25:00+00:00"); + expectedMetadataMap.put(PNFD_NAME.getToken(), "myPnf"); + expectedMetadataMap.put(PNFD_PROVIDER.getToken(), "Acme"); + expectedMetadataMap.put(PNFD_ARCHIVE_VERSION.getToken(), "1.0"); + expectedMetadataMap.put(PNFD_RELEASE_DATE_TIME.getToken(), "2019-03-11T11:25:00+00:00"); expectedMetadataMap.forEach((key, value) -> manifestBuilder.withMetaData(key, value)); @@ -150,7 +153,10 @@ public class ManifestBuilderTest { } private void mockManifestMetadata() { - manifestBuilder.withMetaData(CSARConstants.PNFD_PROVIDER, "test"); + manifestBuilder.withMetaData(PNFD_PROVIDER.getToken(), "provider"); + manifestBuilder.withMetaData(PNFD_NAME.getToken(), "name"); + manifestBuilder.withMetaData(PNFD_RELEASE_DATE_TIME.getToken(), "datetime"); + manifestBuilder.withMetaData(PNFD_ARCHIVE_VERSION.getToken(), "1.0"); } private void mockManifestSource() { diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java index 76a31b2cd5..6dc8e1a5c6 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java @@ -30,12 +30,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; public class ONAPCsarValidatorTest { - ONAPCsarValidator onapCsarValidator; + private ONAPCsarValidator onapCsarValidator; private FileContentHandler contentHandler; private List<String> folderList; @@ -85,9 +85,9 @@ public class ONAPCsarValidatorTest { private void assertExpectedErrors( String testCase, Map<String, List<ErrorMessage>> errors, int expectedErrors){ if(expectedErrors > 0){ List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); - assertTrue(testCase, errorMessages.size() == expectedErrors); + assertEquals(testCase, expectedErrors, errorMessages.size()); }else{ - assertTrue(testCase,errors.size() == expectedErrors); + assertEquals(testCase, expectedErrors, errors.size()); } } } diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java index 328f00ca90..2e0fd8643a 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java @@ -20,35 +20,13 @@ package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; -import org.apache.commons.collections.CollectionUtils; -import org.junit.Before; -import org.junit.Test; -import org.openecomp.core.utilities.file.FileContentHandler; -import org.openecomp.sdc.common.errors.Messages; -import org.openecomp.sdc.common.utils.SdcCommon; -import org.openecomp.sdc.datatypes.error.ErrorLevel; -import org.openecomp.sdc.datatypes.error.ErrorMessage; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.openecomp.sdc.logging.api.Logger; -import org.openecomp.sdc.logging.api.LoggerFactory; - +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.openecomp.sdc.tosca.csar.CSARConstants.PNFD_NAME; -import static org.openecomp.sdc.tosca.csar.CSARConstants.PNFD_PROVIDER; -import static org.openecomp.sdc.tosca.csar.CSARConstants.PNFD_ARCHIVE_VERSION; -import static org.openecomp.sdc.tosca.csar.CSARConstants.PNFD_RELEASE_DATE_TIME; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_CERTIFICATE; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_CHANGE_LOG; @@ -56,14 +34,42 @@ import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_L import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_MANIFEST; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_TESTS; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME; -import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_PRODUCT_NAME; -import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_PROVIDER_ID; -import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_PACKAGE_VERSION; -import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_RELEASE_DATE_TIME; - +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_ARCHIVE_VERSION; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_NAME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_RELEASE_DATE_TIME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_PACKAGE_VERSION; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_PRODUCT_NAME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_PROVIDER_ID; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_RELEASE_DATE_TIME; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_PM_DICTIONARY; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_VES_EVENTS; -import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.*; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.EMPTY_YAML_FILE_PATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.INVALID_YAML_FILE_PATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.SAMPLE_DEFINITION_FILE_PATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.SAMPLE_DEFINITION_IMPORT_FILE_PATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.SAMPLE_SOURCE; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_CHANGELOG_FILEPATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_DEFINITION_FILEPATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_MANIFEST_FILEPATH; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.apache.commons.collections.CollectionUtils; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.common.utils.SdcCommon; +import org.openecomp.sdc.datatypes.error.ErrorLevel; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.tosca.csar.ManifestTokenType; public class SOL004MetaDirectoryValidatorTest { @@ -81,9 +87,9 @@ public class SOL004MetaDirectoryValidatorTest { "TOSCA-Meta-File-Version: 1.0\n"+ "CSAR-Version: 1.1\n"+ "Created-By: Vendor\n"+ - TOSCA_META_ENTRY_DEFINITIONS + SEPARATOR_MF_ATTRIBUTE + "Definitions/MainServiceTemplate.yaml\n"+ - TOSCA_META_ETSI_ENTRY_MANIFEST + SEPARATOR_MF_ATTRIBUTE + "Definitions/MainServiceTemplate.mf\n"+ - TOSCA_META_ETSI_ENTRY_CHANGE_LOG + SEPARATOR_MF_ATTRIBUTE + "Artifacts/changeLog.text\n"; + TOSCA_META_ENTRY_DEFINITIONS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Definitions/MainServiceTemplate.yaml\n"+ + TOSCA_META_ETSI_ENTRY_MANIFEST + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Definitions/MainServiceTemplate.mf\n"+ + TOSCA_META_ETSI_ENTRY_CHANGE_LOG + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Artifacts/changeLog.text\n"; } @Test @@ -92,7 +98,7 @@ public class SOL004MetaDirectoryValidatorTest { "Entry-Definitions: Definitions/MainServiceTemplate.yaml"; handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFileWithInvalidEntry.getBytes(StandardCharsets.UTF_8)); - handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(TestConstants.SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); assertExpectedErrors("TOSCA Meta file with no entries", errors, 1); @@ -109,8 +115,8 @@ public class SOL004MetaDirectoryValidatorTest { folderList.add("Files/Licenses/"); metaFile = metaFile + - TOSCA_META_ETSI_ENTRY_TESTS + SEPARATOR_MF_ATTRIBUTE + entryTestFilePath + "\n" + - TOSCA_META_ETSI_ENTRY_LICENSES + SEPARATOR_MF_ATTRIBUTE + entryLicenseFilePath +"\n"; + TOSCA_META_ETSI_ENTRY_TESTS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + entryTestFilePath + "\n" + + TOSCA_META_ETSI_ENTRY_LICENSES + ATTRIBUTE_VALUE_SEPARATOR.getToken() + entryLicenseFilePath +"\n"; handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); @@ -156,16 +162,16 @@ public class SOL004MetaDirectoryValidatorTest { "TOSCA-Meta-File-Version: " + Integer.MAX_VALUE + "\nCSAR-Version: " + Integer.MAX_VALUE + "\nCreated-By: Bilal Iqbal\n" + - TOSCA_META_ENTRY_DEFINITIONS+ SEPARATOR_MF_ATTRIBUTE + "Definitions/MainServiceTemplate.yaml\n" + - TOSCA_META_ETSI_ENTRY_MANIFEST + SEPARATOR_MF_ATTRIBUTE + "Definitions/MainServiceTemplate.mf\n"+ - TOSCA_META_ETSI_ENTRY_CHANGE_LOG + SEPARATOR_MF_ATTRIBUTE + "Artifacts/changeLog.text"; + TOSCA_META_ENTRY_DEFINITIONS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Definitions/MainServiceTemplate.yaml\n" + + TOSCA_META_ETSI_ENTRY_MANIFEST + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Definitions/MainServiceTemplate.mf\n"+ + TOSCA_META_ETSI_ENTRY_CHANGE_LOG + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Artifacts/changeLog.text"; final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); - handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(TestConstants.SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); manifestBuilder.withSource(TOSCA_DEFINITION_FILEPATH); handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); @@ -437,9 +443,9 @@ public class SOL004MetaDirectoryValidatorTest { "TOSCA-Meta-File-Version: 1.0\n"+ "CSAR-Version: 1.1\n"+ "Created-By: Vendor\n"+ - TOSCA_META_ENTRY_DEFINITIONS + SEPARATOR_MF_ATTRIBUTE + "Definitions/MainServiceTemplate.yaml\n"+ - TOSCA_META_ETSI_ENTRY_MANIFEST + SEPARATOR_MF_ATTRIBUTE +"Definitions/MainServiceTemplate2.mf\n"+ - TOSCA_META_ETSI_ENTRY_CHANGE_LOG + SEPARATOR_MF_ATTRIBUTE +"Artifacts/changeLog.text\n"; + TOSCA_META_ENTRY_DEFINITIONS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Definitions/MainServiceTemplate.yaml\n"+ + TOSCA_META_ETSI_ENTRY_MANIFEST + ATTRIBUTE_VALUE_SEPARATOR.getToken() +"Definitions/MainServiceTemplate2.mf\n"+ + TOSCA_META_ETSI_ENTRY_CHANGE_LOG + ATTRIBUTE_VALUE_SEPARATOR.getToken() +"Artifacts/changeLog.text\n"; final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); @@ -470,8 +476,8 @@ public class SOL004MetaDirectoryValidatorTest { "CSAR-Version: 1.1\n"+ "Created-By: Vendor\n"+ "Entry-Definitions: Definitions/MainServiceTemplate.yaml\n"+ - TOSCA_META_ETSI_ENTRY_MANIFEST + SEPARATOR_MF_ATTRIBUTE + "Definitions/MainServiceTemplate.txt\n"+ - TOSCA_META_ETSI_ENTRY_CHANGE_LOG + SEPARATOR_MF_ATTRIBUTE + "Artifacts/changeLog.text\n"; + TOSCA_META_ETSI_ENTRY_MANIFEST + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Definitions/MainServiceTemplate.txt\n"+ + TOSCA_META_ETSI_ENTRY_CHANGE_LOG + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Artifacts/changeLog.text\n"; final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); @@ -540,10 +546,10 @@ public class SOL004MetaDirectoryValidatorTest { @Test public void testGivenManifestFile_withMetadataContainingMixedPnfVnfMetadata_thenErrorIsReturned() { final ManifestBuilder manifestBuilder = new ManifestBuilder() - .withMetaData(PNFD_NAME, "RadioNode") - .withMetaData(VNF_PROVIDER_ID, "Bilal Iqbal") - .withMetaData(PNFD_ARCHIVE_VERSION, "1.0") - .withMetaData(VNF_RELEASE_DATE_TIME, "2019-12-14T11:25:00+00:00"); + .withMetaData(PNFD_NAME.getToken(), "RadioNode") + .withMetaData(VNF_PROVIDER_ID.getToken(), "Bilal Iqbal") + .withMetaData(PNFD_ARCHIVE_VERSION.getToken(), "1.0") + .withMetaData(VNF_RELEASE_DATE_TIME.getToken(), "2019-12-14T11:25:00+00:00"); handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); @@ -588,8 +594,8 @@ public class SOL004MetaDirectoryValidatorTest { public void testGivenManifestFile_withMetadataMissingMandatoryPnfEntries_thenErrorIsReturned() { final ManifestBuilder manifestBuilder = new ManifestBuilder(); - manifestBuilder.withMetaData(PNFD_NAME, "RadioNode"); - manifestBuilder.withMetaData(PNFD_RELEASE_DATE_TIME, "2019-12-14T11:25:00+00:00"); + manifestBuilder.withMetaData(PNFD_NAME.getToken(), "RadioNode"); + manifestBuilder.withMetaData(PNFD_RELEASE_DATE_TIME.getToken(), "2019-12-14T11:25:00+00:00"); handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); @@ -604,7 +610,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertExpectedErrors("Manifest with metadata missing pnf mandatory entries should return error", errors, 3); + assertExpectedErrors("Manifest with metadata missing pnf mandatory entries should return error", errors, 1); } @@ -612,7 +618,7 @@ public class SOL004MetaDirectoryValidatorTest { public void testGivenManifestFile_withMetadataMissingMandatoryVnfEntries_thenErrorIsReturned() { final ManifestBuilder manifestBuilder = new ManifestBuilder(); - manifestBuilder.withMetaData(VNF_PRODUCT_NAME, "RadioNode"); + manifestBuilder.withMetaData(VNF_PRODUCT_NAME.getToken(), "RadioNode"); handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); @@ -627,7 +633,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertExpectedErrors("Manifest with metadata missing vnf mandatory entries should return error", errors, 4); + assertExpectedErrors("Manifest with metadata missing vnf mandatory entries should return error", errors, 1); } @@ -637,10 +643,10 @@ public class SOL004MetaDirectoryValidatorTest { @Test public void testGivenManifestFile_withMetadataEntriesExceedingTheLimit_thenErrorIsReturned() { final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder() - .withMetaData(PNFD_NAME, "RadioNode") - .withMetaData(PNFD_PROVIDER, "Bilal Iqbal") - .withMetaData(PNFD_ARCHIVE_VERSION, "1.0") - .withMetaData(PNFD_RELEASE_DATE_TIME, "2019-03-11T11:25:00+00:00"); + .withMetaData(PNFD_NAME.getToken(), "RadioNode") + .withMetaData(ManifestTokenType.PNFD_PROVIDER.getToken(), "Bilal Iqbal") + .withMetaData(PNFD_ARCHIVE_VERSION.getToken(), "1.0") + .withMetaData(PNFD_RELEASE_DATE_TIME.getToken(), "2019-03-11T11:25:00+00:00"); handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); @@ -655,7 +661,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertExpectedErrors("Manifest with more than 4 metadata entries should return error", errors, 2); + assertExpectedErrors("Manifest with more than 4 metadata entries should return error", errors, 1); } @Test @@ -663,9 +669,9 @@ public class SOL004MetaDirectoryValidatorTest { final ManifestBuilder manifestBuilder = getPnfManifestSampleBuilder(); metaFile = metaFile + - TOSCA_META_ETSI_ENTRY_TESTS + SEPARATOR_MF_ATTRIBUTE + "Files/Tests\n" + - TOSCA_META_ETSI_ENTRY_LICENSES + SEPARATOR_MF_ATTRIBUTE + "Files/Licenses\n" + - TOSCA_META_ETSI_ENTRY_CERTIFICATE + SEPARATOR_MF_ATTRIBUTE + "Files/Certificates"; + TOSCA_META_ETSI_ENTRY_TESTS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Files/Tests\n" + + TOSCA_META_ETSI_ENTRY_LICENSES + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Files/Licenses\n" + + TOSCA_META_ETSI_ENTRY_CERTIFICATE + ATTRIBUTE_VALUE_SEPARATOR.getToken() + "Files/Certificates"; handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); @@ -908,9 +914,9 @@ public class SOL004MetaDirectoryValidatorTest { final List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); printErrorMessages(errorMessages); if (expectedErrors > 0) { - assertEquals(testCase, errorMessages.size(), expectedErrors); + assertEquals(testCase, expectedErrors, errorMessages.size()); } else { - assertEquals(testCase, errors.size(), expectedErrors); + assertEquals(testCase, expectedErrors, errors.size()); } } @@ -936,18 +942,18 @@ public class SOL004MetaDirectoryValidatorTest { private ManifestBuilder getPnfManifestSampleBuilder() { return new ManifestBuilder() - .withMetaData(PNFD_NAME, "myPnf") - .withMetaData(PNFD_PROVIDER, "ACME") - .withMetaData(PNFD_ARCHIVE_VERSION, "1.0") - .withMetaData(PNFD_RELEASE_DATE_TIME, "2019-03-11T11:25:00+00:00"); + .withMetaData(PNFD_NAME.getToken(), "myPnf") + .withMetaData(ManifestTokenType.PNFD_PROVIDER.getToken(), "ACME") + .withMetaData(PNFD_ARCHIVE_VERSION.getToken(), "1.0") + .withMetaData(PNFD_RELEASE_DATE_TIME.getToken(), "2019-03-11T11:25:00+00:00"); } private ManifestBuilder getVnfManifestSampleBuilder() { return new ManifestBuilder() - .withMetaData(VNF_PRODUCT_NAME, "RadioNode") - .withMetaData(VNF_PROVIDER_ID, "ACME") - .withMetaData(VNF_PACKAGE_VERSION, "1.0") - .withMetaData(VNF_RELEASE_DATE_TIME, "2019-03-11T11:25:00+00:00"); + .withMetaData(VNF_PRODUCT_NAME.getToken(), "RadioNode") + .withMetaData(VNF_PROVIDER_ID.getToken(), "ACME") + .withMetaData(VNF_PACKAGE_VERSION.getToken(), "1.0") + .withMetaData(VNF_RELEASE_DATE_TIME.getToken(), "2019-03-11T11:25:00+00:00"); } private void assertExpectedErrors(List<ErrorMessage> actualErrorList, final List<ErrorMessage> expectedErrorList) { diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java index d9fca4d0e4..344fe8b6f5 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java @@ -27,11 +27,11 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import static org.junit.Assert.assertEquals; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_CHANGE_LOG; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ETSI_ENTRY_MANIFEST; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_CHANGELOG_FILEPATH; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_DEFINITION_FILEPATH; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_MANIFEST_FILEPATH; @@ -74,7 +74,7 @@ public class ValidatorFactoryTest { @Test public void testGivenNonSOL004MetaDirectoryCompliantMetaFile_thenONAPCSARValidatorIsReturned() throws IOException{ metaFile = metaFile + - TOSCA_META_ENTRY_DEFINITIONS + SEPARATOR_MF_ATTRIBUTE + TOSCA_DEFINITION_FILEPATH; + TOSCA_META_ENTRY_DEFINITIONS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + TOSCA_DEFINITION_FILEPATH; handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); assertEquals(ONAPCsarValidator.class, ValidatorFactory.getValidator(handler).getClass()); @@ -84,9 +84,9 @@ public class ValidatorFactoryTest { public void testGivenSOL004MetaDirectoryCompliantMetafile_thenONAPCsarValidatorIsReturned() throws IOException{ metaFile = metaFile + - TOSCA_META_ENTRY_DEFINITIONS + SEPARATOR_MF_ATTRIBUTE + TOSCA_DEFINITION_FILEPATH + "\n" - + TOSCA_META_ETSI_ENTRY_MANIFEST + SEPARATOR_MF_ATTRIBUTE + TOSCA_MANIFEST_FILEPATH + "\n" - + TOSCA_META_ETSI_ENTRY_CHANGE_LOG + SEPARATOR_MF_ATTRIBUTE + TOSCA_CHANGELOG_FILEPATH + "\n"; + TOSCA_META_ENTRY_DEFINITIONS + ATTRIBUTE_VALUE_SEPARATOR.getToken() + TOSCA_DEFINITION_FILEPATH + "\n" + + TOSCA_META_ETSI_ENTRY_MANIFEST + ATTRIBUTE_VALUE_SEPARATOR.getToken() + TOSCA_MANIFEST_FILEPATH + "\n" + + TOSCA_META_ETSI_ENTRY_CHANGE_LOG + ATTRIBUTE_VALUE_SEPARATOR.getToken() + TOSCA_CHANGELOG_FILEPATH + "\n"; handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); assertEquals(SOL004MetaDirectoryValidator.class, ValidatorFactory.getValidator(handler).getClass()); diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/upload/csar/UploadCSARFileTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/upload/csar/UploadCSARFileTest.java index 77e519c502..122809896e 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/upload/csar/UploadCSARFileTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/upload/csar/UploadCSARFileTest.java @@ -138,8 +138,9 @@ public class UploadCSARFileTest { candidateManager.upload(vspDetails, onboardPackageInfo); assertEquals(1, response.getErrors().size()); assertEquals(response.getErrors().values().iterator().next().get(0).getMessage(), - "Manifest " + - "contains invalid line : aaa: vCSCF"); + Messages.MANIFEST_ERROR_WITH_LINE + .formatMessage(Messages.MANIFEST_START_METADATA.getErrorMessage(), 1, "aaa: vCSCF") + ); } } diff --git a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java index 7d2f8b2a36..2e30126985 100644 --- a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java +++ b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java @@ -27,16 +27,30 @@ public enum Messages { CSAR_FILE_NOT_FOUND("Each CSAR file must contain %s file."), CSAR_DIRECTORIES_NOT_ALLOWED("Directory : %s , is not allowed."), CSAR_FILES_NOT_ALLOWED("File : %s , are not allowed."), - MANIFEST_INVALID_LINE("Manifest contains invalid line : %s"), + MANIFEST_INVALID_LINE("Manifest contains invalid line: %s: %s"), + MANIFEST_START_METADATA("Manifest must starts with 'metadata:'"), MANIFEST_NO_METADATA("Manifest must contain metadata"), MANIFEST_NO_SOURCES("Manifest must contain Source"), MANIFEST_METADATA_MISSING_ENTRY("Manifest metadata missing entry %s"), MANIFEST_INVALID_NAME("Manifest file %s and TOSCA definitions file %s must have the same name"), MANIFEST_INVALID_EXT("Manifest file must have extension \".mf\" "), MANIFEST_METADATA_INVALID_ENTRY("Manifest metadata should only have pnf or vnf entries"), + MANIFEST_METADATA_INVALID_ENTRY1("Invalid Manifest metadata entry: '%s'."), + MANIFEST_METADATA_DUPLICATED_ENTRY("Duplicated Manifest metadata entry: '%s'."), + MANIFEST_METADATA_UNEXPECTED_ENTRY_TYPE("Manifest metadata should have either pnf or vnf entries, not both together"), MANIFEST_INVALID_PNF_METADATA("%s TOSCA.meta file is applicable for VF only"), - MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT("Manifest metadata must only have the required number [%s] of values"), - MANIFEST_EMPTY("Manifest must contain data"), + MANIFEST_INVALID_NON_MANO_KEY("Invalid non mano key '%s'"), + MANIFEST_EMPTY_NON_MANO_KEY("Expecting a 'Source' entry for the non mano key '%s'"), + MANIFEST_EMPTY_NON_MANO_SOURCE("Empty non mano source"), + MANIFEST_EXPECTED_HASH_ENTRY("Expected Hash entry"), + MANIFEST_EXPECTED_HASH_VALUE("Expected Hash entry value"), + MANIFEST_EXPECTED_SOURCE_PATH("Expected Source entry path"), + MANIFEST_EXPECTED_ALGORITHM_VALUE("Expected Algorithm entry value"), + MANIFEST_EXPECTED_ALGORITHM_BEFORE_HASH("Expected 'Algorithm' entry before 'Hash' entry"), + MANIFEST_DUPLICATED_CMS_SIGNATURE("Duplicated CMS signature"), + MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT("Manifest metadata must only have the required number [%s] of entries"), + MANIFEST_EMPTY("The manifest is empty"), + MANIFEST_ERROR_WITH_LINE("%s;%nAt line %s: '%s'."), MANIFEST_PARSER_INTERNAL("Invalid manifest file"), METADATA_PARSER_INTERNAL("Invalid Metadata file"), METADATA_MISSING_OPTIONAL_FOLDERS("Missing folder %s in package"), @@ -211,7 +225,7 @@ public enum Messages { * @return * The formatted message. */ - public String formatMessage(final String... params) { + public String formatMessage(final Object... params) { return String.format(errorMessage, params); } diff --git a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/errors/ErrorMessagesFormatBuilder.java b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/errors/ErrorMessagesFormatBuilder.java index bd5a2ccc3c..e3ed721fdd 100644 --- a/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/errors/ErrorMessagesFormatBuilder.java +++ b/openecomp-be/lib/openecomp-sdc-validation-lib/openecomp-sdc-validation-api/src/main/java/org/openecomp/core/validation/errors/ErrorMessagesFormatBuilder.java @@ -26,7 +26,7 @@ import org.openecomp.core.validation.ErrorMessageCode; public class ErrorMessagesFormatBuilder { private static final String MESSAGE_PATTERN = "[%s]: %s"; - public static String getErrorWithParameters(String error, String... params) { + public static String getErrorWithParameters(String error, Object... params) { return String.format(error, params); } /** diff --git a/openecomp-be/lib/openecomp-tosca-lib/pom.xml b/openecomp-be/lib/openecomp-tosca-lib/pom.xml index 33f5168869..9029efca4d 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/pom.xml +++ b/openecomp-be/lib/openecomp-tosca-lib/pom.xml @@ -61,6 +61,18 @@ <version>${logback.version}</version> </dependency> <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-library</artifactId> + <version>${hamcrest.version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AbstractOnboardingManifest.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AbstractOnboardingManifest.java index a0c346c677..7cc11e564d 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AbstractOnboardingManifest.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AbstractOnboardingManifest.java @@ -19,10 +19,6 @@ package org.openecomp.sdc.tosca.csar; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -import org.openecomp.sdc.common.errors.Messages; -import org.openecomp.sdc.logging.api.Logger; -import org.openecomp.sdc.logging.api.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -35,21 +31,27 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; -import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters; -import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_PNF_METADATA; -import static org.openecomp.sdc.tosca.csar.CSARConstants.METADATA_MF_ATTRIBUTE; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; - - abstract class AbstractOnboardingManifest implements Manifest{ +abstract class AbstractOnboardingManifest implements Manifest { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractOnboardingManifest.class); - private static final int MAX_ALLOWED_MANIFEST_META_ENTRIES = 4; + protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractOnboardingManifest.class); + protected static final int MAX_ALLOWED_MANIFEST_META_ENTRIES = 4; protected Map<String, String> metadata; protected List<String> sources; - protected List<String> errors; protected Map<String, List<String>> nonManoSources; - protected ResourceTypeEnum type; + protected Map<String, AlgorithmDigest> sourceAndChecksumMap = new HashMap<>(); + protected String cmsSignature; + protected List<String> errors; + protected boolean continueToProcess; + protected String currentLine; + protected Iterator<String> linesIterator; + protected int currentLineNumber; protected AbstractOnboardingManifest() { errors = new ArrayList<>(); @@ -59,122 +61,327 @@ import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; } @Override - public Optional<ResourceTypeEnum> getType(){ - if(errors.isEmpty() && !metadata.isEmpty() && metadata.size() == MAX_ALLOWED_MANIFEST_META_ENTRIES) { - for (String key : metadata.keySet()) { - if (MANIFEST_PNF_METADATA.stream().anyMatch(key::equals)) { - return Optional.of(ResourceTypeEnum.PNF); - } - return Optional.of(ResourceTypeEnum.VF); - } + public Optional<ResourceTypeEnum> getType() { + if (!isValid()) { + return Optional.empty(); } - return Optional.empty(); + final String firstKey = metadata.keySet().iterator().next(); + final ManifestTokenType manifestTokenType = ManifestTokenType.parse(firstKey).orElse(null); + if (manifestTokenType == null) { + return Optional.empty(); + } + if (manifestTokenType.isMetadataPnfEntry()) { + return Optional.of(ResourceTypeEnum.PNF); + } + return Optional.of(ResourceTypeEnum.VF); } @Override - public void parse(InputStream is) { + public void parse(final InputStream manifestAsStream) { try { - ImmutableList<String> lines = readAllLines(is); + final ImmutableList<String> lines = readAllLines(manifestAsStream); + continueToProcess = true; + currentLineNumber = 0; processManifest(lines); - } catch (IOException e){ - LOGGER.error(e.getMessage(),e); + } catch (IOException e) { + LOGGER.error(e.getMessage(), e); errors.add(Messages.MANIFEST_PARSER_INTERNAL.getErrorMessage()); } } - protected void processManifest(ImmutableList<String> lines) { - if (isEmptyManifest(lines)){ + /** + * Process the manifest lines, reporting an error when detected. + * + * @param lines the manifest lines + */ + protected void processManifest(final ImmutableList<String> lines) { + if (isEmptyManifest(lines)) { return; } - Iterator<String> iterator = lines.iterator(); - //SOL004 #4.3.2: The manifest file shall start with the package metadata - String line = iterator.next(); - if (!isMetadata(line)) { + linesIterator = lines.iterator(); + readNextNonEmptyLine(); + if (!getCurrentLine().isPresent()) { + errors.add(Messages.MANIFEST_EMPTY.getErrorMessage()); return; } - //handle metadata - processMetadata(iterator); - if (errors.isEmpty() && metadata.isEmpty()) { - errors.add(Messages.MANIFEST_NO_METADATA.getErrorMessage()); - } - } - - protected abstract void processMetadata(Iterator<String> iterator); - - protected boolean isEmptyLine(Iterator<String> iterator, String line) { - if(line.isEmpty()){ - processMetadata(iterator); - return true; - } - return false; - } - - protected boolean isInvalidLine(String line, String[] metaSplit) { - if (metaSplit.length < 2){ - reportError(line); - return true; - } - return false; - } - - protected boolean isMetadata(String line) { - if(line.trim().equals(METADATA_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE)){ - return true; - } - reportError(line); - return false; - } - - protected boolean isEmptyManifest(ImmutableList<String> lines) { - if(lines == null || lines.isEmpty()){ - errors.add(Messages.MANIFEST_EMPTY.getErrorMessage()); - return true; - } - return false; - } - - protected void reportError(String line) { - errors.add(getErrorWithParameters(Messages.MANIFEST_INVALID_LINE.getErrorMessage(), line)); - } - - protected ImmutableList<String> readAllLines(InputStream is) throws IOException { - if(is == null){ - throw new IOException("Input Stream cannot be null!"); - } - ImmutableList.Builder<String> builder = ImmutableList.<String> builder(); - try (BufferedReader bufferedReader = new BufferedReader( - new InputStreamReader(is, StandardCharsets.UTF_8.newDecoder()))) { + + processMetadata(); + processBody(); + } + + /** + * Process the metadata part of the Manifest file. + */ + protected abstract void processMetadata(); + + /** + * Process the other parts from manifest different than metadata. + */ + protected abstract void processBody(); + + /** + * Read the manifest as a list of lines. + * + * @param manifestAsStream The manifest file input stream + * @return The manifest as a list of string + * @throws IOException when the input stream is null or a read problem happened. + */ + protected ImmutableList<String> readAllLines(final InputStream manifestAsStream) throws IOException { + if (manifestAsStream == null) { + throw new IOException("Manifest Input Stream cannot be null."); + } + final ImmutableList.Builder<String> builder = ImmutableList.builder(); + try (final BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(manifestAsStream, StandardCharsets.UTF_8.newDecoder()))) { bufferedReader.lines().forEach(builder::add); } return builder.build(); } + /** + * Checks if the line is a {@link ManifestTokenType#METADATA} entry. + * + * @param line The line to check + * @return {@code true} if the line is a 'metadata' entry, {@code false} otherwise. + */ + protected boolean isMetadata(final String line) { + return line.trim() + .equals(ManifestTokenType.METADATA.getToken() + ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR.getToken()); + } + + /** + * Checks if the the entry is a valid metadata entry. + * + * @param metadataEntry the entry to be evaluated + * @return {@code true} if the entry is a valid metadata entry, {@code false} otherwise. + */ + protected boolean isMetadataEntry(final String metadataEntry) { + final Optional<ManifestTokenType> manifestTokenType = ManifestTokenType.parse(metadataEntry); + return manifestTokenType.map(ManifestTokenType::isMetadataEntry).orElse(false); + } + + /** + * Checks if the manifest is empty + * + * @param lines the manifest parsed as a string lines list + * @return {@code true} if the manifest is empty, {@code false} otherwise. + */ + protected boolean isEmptyManifest(final ImmutableList<String> lines) { + if (lines == null || lines.isEmpty()) { + errors.add(Messages.MANIFEST_EMPTY.getErrorMessage()); + return true; + } + return false; + } + + /** + * Reports a manifest invalid line error occurred in the current line. + */ + protected void reportInvalidLine() { + reportInvalidLine(currentLineNumber, getCurrentLine().orElse("")); + } + + /** + * Reports a manifest invalid line error. + * + * @param lineNumber the line number + * @param line the line + */ + protected void reportInvalidLine(final int lineNumber, final String line) { + errors.add(Messages.MANIFEST_INVALID_LINE.formatMessage(lineNumber, line)); + } + + /** + * Reports a manifest error occurred in the current line. + * + * @param message The error message + * @param params The message params + */ + protected void reportError(final Messages message, final Object... params) { + reportError(currentLineNumber, getCurrentLine().orElse(""), message, params); + } + + /** + * Reports a manifest error occurred in the specified line. + * + * @param lineNumber The line number + * @param line The line + * @param message The error message + * @param params The message params + */ + protected void reportError(final int lineNumber, final String line, final Messages message, + final Object... params) { + errors.add(Messages.MANIFEST_ERROR_WITH_LINE.formatMessage(message.formatMessage(params), lineNumber, line)); + } + + /** + * Checks if the manifest is valid. + * + * @return {@code true} if the manifest is valid, {@code false} otherwise. + */ + public boolean isValid() { + return errors.isEmpty(); + } + + /** + * Reads the next non empty line in the manifest. Updates the current line and line number. + * + * @return the next non empty line. If there is no more lines, an empty value. + */ + protected Optional<String> readNextNonEmptyLine() { + while (linesIterator.hasNext()) { + final String line = linesIterator.next().trim(); + currentLineNumber++; + if (!line.isEmpty()) { + currentLine = line; + return getCurrentLine(); + } + currentLine = null; + } + + if (getCurrentLine().isPresent()) { + currentLineNumber++; + currentLine = null; + } + + return getCurrentLine(); + } + + /** + * Gets the current line. + * + * @return the current line. + */ + protected Optional<String> getCurrentLine() { + return Optional.ofNullable(currentLine); + } + + /** + * Reads the current line entry name. The entry name and value must be separated by {@link + * ManifestTokenType#ATTRIBUTE_VALUE_SEPARATOR}. + * + * @return the entry value + */ + protected Optional<String> readCurrentEntryName() { + final Optional<String> line = getCurrentLine(); + if (line.isPresent()) { + return readEntryName(line.get()); + } + + return Optional.empty(); + } + + /** + * Read a entry name. The entry name and value must be separated by {@link ManifestTokenType#ATTRIBUTE_VALUE_SEPARATOR}. + * + * @param line the entry line + * @return returns the entry name + */ + protected Optional<String> readEntryName(final String line) { + if (StringUtils.isEmpty(line)) { + return Optional.empty(); + } + if (!line.contains(ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR.getToken())) { + return Optional.empty(); + } + final String attribute = line.substring(0, line.indexOf(ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR.getToken())).trim(); + if (StringUtils.isEmpty(attribute)) { + return Optional.empty(); + } + + return Optional.of(attribute); + } + + /** + * Reads the current line entry value. The entry name and value must be separated by {@link + * ManifestTokenType#ATTRIBUTE_VALUE_SEPARATOR}. + * + * @return the entry value + */ + protected Optional<String> readCurrentEntryValue() { + final Optional<String> line = getCurrentLine(); + if (line.isPresent()) { + return readEntryValue(line.get()); + } + + return Optional.empty(); + } + + /** + * Reads a entry value. The entry name and value must be separated by {@link ManifestTokenType#ATTRIBUTE_VALUE_SEPARATOR}. + * + * @param line the entry line + * @return the entry value + */ + protected Optional<String> readEntryValue(final String line) { + if (StringUtils.isEmpty(line)) { + return Optional.empty(); + } + if (!line.contains(ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR.getToken())) { + return Optional.empty(); + } + final String value = line.substring(line.indexOf(ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR.getToken()) + 1).trim(); + if (StringUtils.isEmpty(value)) { + return Optional.empty(); + } + + return Optional.of(value); + } + + /** + * Adds a entry to the metadata map. Only accepts new entries. If the entry is duplicated a manifest error is + * reported. + * + * @param entry the metadata entry + * @param value the entry value + * @return {@code true} if the entry was added, {@code false} otherwise. + */ + protected boolean addToMetadata(final String entry, final String value) { + if (metadata.containsKey(entry)) { + reportError(Messages.MANIFEST_METADATA_DUPLICATED_ENTRY, entry); + return false; + } + + metadata.put(entry, value); + return true; + } + + public List<String> getErrors() { + return ImmutableList.copyOf(errors); + } + public Map<String, String> getMetadata() { - if (!isValid()){ + if (!isValid()) { return Collections.emptyMap(); } return ImmutableMap.copyOf(metadata); } public List<String> getSources() { - if (!isValid()){ + if (!isValid()) { return Collections.emptyList(); } return ImmutableList.copyOf(sources); } - public List<String> getErrors() { - return ImmutableList.copyOf(errors); + public Map<String, List<String>> getNonManoSources() { + if (!isValid()) { + return Collections.emptyMap(); + } + return ImmutableMap.copyOf(nonManoSources); } - public boolean isValid() { - return errors.isEmpty(); + @Override + public Optional<String> getCmsSignature() { + return Optional.ofNullable(cmsSignature); } - public Map<String, List<String>> getNonManoSources() { - if (!isValid()){ - return Collections.emptyMap(); + @Override + public Optional<Map<String, AlgorithmDigest>> getSourceAndChecksumMap() { + if (MapUtils.isEmpty(sourceAndChecksumMap)) { + return Optional.empty(); } - return ImmutableMap.copyOf(nonManoSources); + + return Optional.of(ImmutableMap.copyOf(sourceAndChecksumMap)); } } diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AlgorithmDigest.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AlgorithmDigest.java new file mode 100644 index 0000000000..8ce0fb650b --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AlgorithmDigest.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation + * ================================================================================ + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.tosca.csar; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * Represents a manifest Hash algorithm and Digest + */ +@Getter +@AllArgsConstructor +public class AlgorithmDigest { + private final String hashAlgorithm; + private final String digest; +} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/CSARConstants.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/CSARConstants.java index 7a42758322..1de91f9549 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/CSARConstants.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/CSARConstants.java @@ -18,6 +18,14 @@ package org.openecomp.sdc.tosca.csar; import static com.google.common.collect.ImmutableSet.of; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_ARCHIVE_VERSION; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_NAME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_PROVIDER; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.PNFD_RELEASE_DATE_TIME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_PACKAGE_VERSION; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_PRODUCT_NAME; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_PROVIDER_ID; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.VNF_RELEASE_DATE_TIME; import com.google.common.collect.ImmutableSet; @@ -34,37 +42,21 @@ public class CSARConstants { public static final String TOSCA_META_CSAR_VERSION_ENTRY = "CSAR-Version"; public static final String TOSCA_META_CREATED_BY_ENTRY = "Created-By"; public static final String TOSCA_META_ENTRY_DEFINITIONS ="Entry-Definitions"; - public static final String TOSCA_META_ETSI_ENTRY_MANIFEST ="ETSI-Entry-Manifest"; - public static final String TOSCA_META_ETSI_ENTRY_CHANGE_LOG ="ETSI-Entry-Change-Log"; + public static final String TOSCA_META_ETSI_ENTRY_MANIFEST = "ETSI-Entry-Manifest"; + public static final String TOSCA_META_ETSI_ENTRY_CHANGE_LOG = "ETSI-Entry-Change-Log"; public static final String TOSCA_META_ETSI_ENTRY_TESTS = "ETSI-Entry-Tests"; public static final String TOSCA_META_ETSI_ENTRY_LICENSES = "ETSI-Entry-Licenses"; public static final String TOSCA_META_ETSI_ENTRY_CERTIFICATE = "ETSI-Entry-Certificate"; public static final ImmutableSet<String> ELIGIBLE_FILES = of(MAIN_SERVICE_TEMPLATE_MF_FILE_NAME,MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME); - public static final String PNFD_PROVIDER = "pnfd_provider"; - public static final String PNFD_NAME = "pnfd_name"; - public static final String PNFD_RELEASE_DATE_TIME = "pnfd_release_date_time"; - public static final String PNFD_ARCHIVE_VERSION = "pnfd_archive_version"; public static final ImmutableSet<String> MANIFEST_PNF_METADATA = - of(PNFD_PROVIDER, PNFD_NAME, PNFD_RELEASE_DATE_TIME, PNFD_ARCHIVE_VERSION); - - public static final String VNF_PROVIDER_ID = "vnf_provider_id"; - public static final String VNF_PRODUCT_NAME = "vnf_product_name"; - public static final String VNF_RELEASE_DATE_TIME = "vnf_release_date_time"; - public static final String VNF_PACKAGE_VERSION = "vnf_package_version"; + of(PNFD_PROVIDER.getToken(), PNFD_NAME.getToken(), PNFD_RELEASE_DATE_TIME.getToken(), + PNFD_ARCHIVE_VERSION.getToken()); public static final ImmutableSet<String> MANIFEST_VNF_METADATA = - of(VNF_PROVIDER_ID, VNF_PRODUCT_NAME, VNF_RELEASE_DATE_TIME, VNF_PACKAGE_VERSION); - + of(VNF_PROVIDER_ID.getToken(), VNF_PRODUCT_NAME.getToken(), VNF_RELEASE_DATE_TIME.getToken(), + VNF_PACKAGE_VERSION.getToken()); public static final int MANIFEST_METADATA_LIMIT = 4; - public static final String METADATA_MF_ATTRIBUTE = "metadata"; - public static final String SOURCE_MF_ATTRIBUTE = "Source"; - public static final String ALGORITHM_MF_ATTRIBUTE = "Algorithm"; - public static final String HASH_MF_ATTRIBUTE = "Hash"; - public static final String CMS_BEGIN = "----BEGIN CMS-----"; - public static final String CMD_END = "----END CMS-----"; - public static final String SEPARATOR_MF_ATTRIBUTE = ":"; - public static final String NON_MANO_MF_ATTRIBUTE = "non_mano_artifact_sets"; public static final String TOSCA_META_ORIG_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta.original"; public static final String TOSCA_META_FILE_VERSION = "1.0"; diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/Manifest.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/Manifest.java index c11f4a3ddc..c0ccbbc14d 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/Manifest.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/Manifest.java @@ -20,11 +20,11 @@ package org.openecomp.sdc.tosca.csar; -import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Optional; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; public interface Manifest { @@ -70,4 +70,18 @@ public interface Manifest { * @return enum for type values */ Optional<ResourceTypeEnum> getType(); + + /** + * Gets the CMS manifest signature if present in manifest + * @return + * the CMS manifest signature. + */ + Optional<String> getCmsSignature(); + + /** + * Gets the Map of source path and it correspondent checksum. + * @return + * The source and checksum map. + */ + Optional<Map<String, AlgorithmDigest>> getSourceAndChecksumMap(); } diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ManifestTokenType.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ManifestTokenType.java new file mode 100644 index 0000000000..68ad91d29a --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ManifestTokenType.java @@ -0,0 +1,84 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation + * ================================================================================ + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.tosca.csar; + +import java.util.Arrays; +import java.util.Optional; + +public enum ManifestTokenType { + ALGORITHM("Algorithm"), + ATTRIBUTE_VALUE_SEPARATOR(":"), + CMS_BEGIN("-----BEGIN CMS-----"), + CMS_END("-----END CMS-----"), + HASH("Hash"), + METADATA("metadata"), + NON_MANO_ARTIFACT_SETS("non_mano_artifact_sets"), + SOURCE("Source"), + VNF_PRODUCT_NAME("vnf_product_name"), + VNF_PROVIDER_ID("vnf_provider_id"), + VNF_PACKAGE_VERSION("vnf_package_version"), + VNF_RELEASE_DATE_TIME("vnf_release_date_time"), + PNFD_NAME("pnfd_name"), + PNFD_PROVIDER("pnfd_provider"), + PNFD_ARCHIVE_VERSION("pnfd_archive_version"), + PNFD_RELEASE_DATE_TIME("pnfd_release_date_time"); + + private final String token; + + ManifestTokenType(final String token) { + this.token = token; + } + + public String getToken() { + return token; + } + + public static Optional<ManifestTokenType> parse(final String token) { + return Arrays.stream(values()).filter(it -> it.getToken() != null && it.getToken().equals(token)).findFirst(); + } + + public boolean isMetadataEntry() { + return isMetadataVnfEntry() || isMetadataPnfEntry(); + } + + public boolean isMetadataVnfEntry() { + switch (this) { + case VNF_PRODUCT_NAME: + case VNF_PROVIDER_ID: + case VNF_PACKAGE_VERSION: + case VNF_RELEASE_DATE_TIME: + return true; + default: + return false; + } + } + + public boolean isMetadataPnfEntry() { + switch (this) { + case PNFD_NAME: + case PNFD_PROVIDER: + case PNFD_ARCHIVE_VERSION: + case PNFD_RELEASE_DATE_TIME: + return true; + default: + return false; + } + } +} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ONAPManifestOnboarding.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ONAPManifestOnboarding.java index 2c4cc3a81f..02ee12db13 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ONAPManifestOnboarding.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ONAPManifestOnboarding.java @@ -21,44 +21,54 @@ package org.openecomp.sdc.tosca.csar; import com.google.common.collect.ImmutableList; +import java.util.Optional; import org.openecomp.sdc.common.errors.Messages; -import java.util.Iterator; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SOURCE_MF_ATTRIBUTE; - -public class ONAPManifestOnboarding extends AbstractOnboardingManifest implements Manifest { +public class ONAPManifestOnboarding extends AbstractOnboardingManifest { @Override protected void processManifest(ImmutableList<String> lines) { super.processManifest(lines); if (errors.isEmpty() && sources.isEmpty()) { - errors.add(Messages.MANIFEST_NO_SOURCES.getErrorMessage()); + errors.add(Messages.MANIFEST_NO_SOURCES.getErrorMessage()); } } @Override - protected void processMetadata(Iterator<String> iterator) { - if(!iterator.hasNext()){ - return; - } - String line = iterator.next(); - if(isEmptyLine(iterator, line)) { - return; - } - String[] metaSplit = line.split(SEPARATOR_MF_ATTRIBUTE); - if (isInvalidLine(line, metaSplit)) { + protected void processMetadata() { + Optional<String> currentLine = getCurrentLine(); + if (!currentLine.isPresent() || !isMetadata(currentLine.get())) { + reportError(Messages.MANIFEST_START_METADATA); + continueToProcess = false; return; } - if (!metaSplit[0].equals(SOURCE_MF_ATTRIBUTE)){ - String value = line.substring((metaSplit[0] + SEPARATOR_MF_ATTRIBUTE).length()).trim(); - metadata.put(metaSplit[0].trim(),value.trim()); - processMetadata(iterator); - }else if(metaSplit[0].startsWith(SOURCE_MF_ATTRIBUTE)){ - String value = line.substring((metaSplit[0] + SEPARATOR_MF_ATTRIBUTE).length()).trim(); - sources.add(value); - processMetadata(iterator); + currentLine = readNextNonEmptyLine(); + + while (currentLine.isPresent() && continueToProcess) { + final String line = currentLine.get(); + final String entry = readEntryName(line).orElse(null); + if (entry == null) { + reportInvalidLine(); + } + final String value = readEntryValue(line).orElse(null); + if (value == null) { + reportInvalidLine(); + } + + final ManifestTokenType tokenType = ManifestTokenType.parse(entry).orElse(null); + if (tokenType == ManifestTokenType.SOURCE) { + sources.add(value); + } else { + addToMetadata(entry, value); + continueToProcess = isValid(); + } + currentLine = readNextNonEmptyLine(); } } + @Override + protected void processBody() { + //no implementation + } + } diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingToscaMetadata.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingToscaMetadata.java index 8d603cccb3..3fc55adb51 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingToscaMetadata.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingToscaMetadata.java @@ -36,10 +36,10 @@ import java.util.List; import java.util.Map; import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; +import static org.openecomp.sdc.tosca.csar.ManifestTokenType.ATTRIBUTE_VALUE_SEPARATOR; -public class OnboardingToscaMetadata implements ToscaMetadata{ +public class OnboardingToscaMetadata implements ToscaMetadata { private Map<String, String> metaEntries; private List<ErrorMessage> errors; @@ -66,7 +66,7 @@ public class OnboardingToscaMetadata implements ToscaMetadata{ if (line.isEmpty()) { return meta; } - String[] entry = line.split(SEPARATOR_MF_ATTRIBUTE); + String[] entry = line.split(ATTRIBUTE_VALUE_SEPARATOR.getToken()); //No empty keys allowed, no empty values allowed if (entry.length < 2 || entry[0].isEmpty()) { meta.errors.add(new ErrorMessage(ErrorLevel.ERROR, getErrorWithParameters( diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboarding.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboarding.java index b5b3d9cdce..bb0b07a63f 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboarding.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboarding.java @@ -21,114 +21,295 @@ package org.openecomp.sdc.tosca.csar; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import java.util.Map.Entry; +import java.util.Optional; +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.common.errors.Messages; -import static org.openecomp.sdc.tosca.csar.CSARConstants.ALGORITHM_MF_ATTRIBUTE; -import static org.openecomp.sdc.tosca.csar.CSARConstants.CMD_END; -import static org.openecomp.sdc.tosca.csar.CSARConstants.CMS_BEGIN; -import static org.openecomp.sdc.tosca.csar.CSARConstants.HASH_MF_ATTRIBUTE; -import static org.openecomp.sdc.tosca.csar.CSARConstants.NON_MANO_MF_ATTRIBUTE; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPARATOR_MF_ATTRIBUTE; -import static org.openecomp.sdc.tosca.csar.CSARConstants.SOURCE_MF_ATTRIBUTE; - +/** + * Processes a SOL004 Manifest. + */ public class SOL004ManifestOnboarding extends AbstractOnboardingManifest { @Override - protected void processMetadata(Iterator<String> iterator) { - if(!iterator.hasNext()){ + protected void processMetadata() { + Optional<String> currentLine = getCurrentLine(); + //SOL004 #4.3.2: The manifest file shall start with the package metadata + if (!currentLine.isPresent() || !isMetadata(currentLine.get())) { + reportError(Messages.MANIFEST_START_METADATA); + continueToProcess = false; return; } - String line = iterator.next(); - if(isEmptyLine(iterator, line)){ + while (continueToProcess) { + currentLine = readNextNonEmptyLine(); + if (!currentLine.isPresent()) { + continueToProcess = validateMetadata(); + return; + } + final String metadataLine = currentLine.get(); + final String metadataEntry = readEntryName(metadataLine).orElse(null); + if (!isMetadataEntry(metadataEntry)) { + if (metadata.size() < MAX_ALLOWED_MANIFEST_META_ENTRIES) { + reportError(Messages.MANIFEST_METADATA_INVALID_ENTRY1, metadataLine); + continueToProcess = false; + return; + } + continueToProcess = validateMetadata(); + return; + } + final String metadataValue = readEntryValue(metadataLine).orElse(null); + addToMetadata(metadataEntry, metadataValue); + continueToProcess = isValid(); + } + readNextNonEmptyLine(); + } + + @Override + protected void processBody() { + while (continueToProcess) { + final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null); + if (manifestTokenType == null) { + getCurrentLine().ifPresent(line -> reportInvalidLine()); + break; + } + + switch (manifestTokenType) { + case CMS_BEGIN: + readCmsSignature(); + break; + case NON_MANO_ARTIFACT_SETS: + processNonManoArtifactEntry(); + continueToProcess = false; + break; + case SOURCE: + processSource(); + break; + default: + getCurrentLine().ifPresent(line -> reportInvalidLine()); + continueToProcess = false; + break; + } + } + } + + /** + * Processes the {@link ManifestTokenType#NON_MANO_ARTIFACT_SETS} entry. + */ + private void processNonManoArtifactEntry() { + Optional<String> currentLine = readNextNonEmptyLine(); + while (currentLine.isPresent()) { + final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null); + if (manifestTokenType != null) { + reportError(Messages.MANIFEST_INVALID_NON_MANO_KEY, manifestTokenType.getToken()); + continueToProcess = false; + return; + } + final String nonManoKey = readCurrentEntryName().orElse(null); + if (nonManoKey == null) { + reportError(Messages.MANIFEST_INVALID_NON_MANO_KEY, currentLine.get()); + continueToProcess = false; + return; + } + readNextNonEmptyLine(); + final List<String> nonManoSourceList = readNonManoSourceList(); + if (!isValid()) { + continueToProcess = false; + return; + } + if (nonManoSourceList.isEmpty()) { + reportError(Messages.MANIFEST_EMPTY_NON_MANO_KEY, nonManoKey); + continueToProcess = false; + return; + } + if (nonManoSources.get(nonManoKey) == null) { + nonManoSources.put(nonManoKey, nonManoSourceList); + } else { + nonManoSources.get(nonManoKey).addAll(nonManoSourceList); + } + currentLine = getCurrentLine(); + } + } + + /** + * Processes {@link ManifestTokenType#SOURCE} entries in {@link ManifestTokenType#NON_MANO_ARTIFACT_SETS}. + * + * @return A list of sources paths + */ + private List<String> readNonManoSourceList() { + final List<String> nonManoSourceList = new ArrayList<>(); + while (getCurrentLine().isPresent()) { + final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null); + if (manifestTokenType != ManifestTokenType.SOURCE) { + break; + } + + final String value = readCurrentEntryValue().orElse(null); + if (!StringUtils.isEmpty(value)) { + nonManoSourceList.add(value); + } else { + reportError(Messages.MANIFEST_EMPTY_NON_MANO_SOURCE); + break; + } + + readNextNonEmptyLine(); + } + return nonManoSourceList; + } + + /** + * Reads a manifest CMS signature. + */ + private void readCmsSignature() { + if (cmsSignature != null) { + reportError(Messages.MANIFEST_DUPLICATED_CMS_SIGNATURE); + continueToProcess = false; return; } - String[] metaSplit = line.split(SEPARATOR_MF_ATTRIBUTE); - if (isInvalidLine(line, metaSplit)) { + Optional<String> currentLine = readNextNonEmptyLine(); + if(!getCurrentLine().isPresent()) { return; } - if (!metaSplit[0].equals(SOURCE_MF_ATTRIBUTE) && !metaSplit[0].equals(NON_MANO_MF_ATTRIBUTE)){ - String value = line.substring((metaSplit[0] + SEPARATOR_MF_ATTRIBUTE).length()).trim(); - metadata.put(metaSplit[0].trim(),value.trim()); - processMetadata(iterator); - } else { - processSourcesAndNonManoSources(iterator, line); + StringBuilder stringBuilder = new StringBuilder(); + while (currentLine.isPresent() && detectLineEntry().orElse(null) != ManifestTokenType.CMS_END) { + stringBuilder.append(currentLine.get()); + stringBuilder.append("\n"); + currentLine = readNextNonEmptyLine(); + } + + if (currentLine.isPresent()) { + cmsSignature = stringBuilder.toString(); + readNextNonEmptyLine(); } } - private void processSourcesAndNonManoSources(Iterator<String> iterator, String prevLine) { - if(prevLine.isEmpty()){ - if(iterator.hasNext()){ - processSourcesAndNonManoSources(iterator, iterator.next()); + /** + * Detects the current line manifest token. + * + * @return the current line manifest token. + */ + private Optional<ManifestTokenType> detectLineEntry() { + final Optional<String> currentLine = getCurrentLine(); + if (currentLine.isPresent()) { + final String line = currentLine.get(); + final String entry = readEntryName(line).orElse(null); + if (entry == null) { + return ManifestTokenType.parse(line); + } else { + return ManifestTokenType.parse(entry); } - } else if(prevLine.startsWith(SOURCE_MF_ATTRIBUTE+ SEPARATOR_MF_ATTRIBUTE)){ - processSource(iterator, prevLine); - } - else if(prevLine.startsWith(ALGORITHM_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE) || - prevLine.startsWith(HASH_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE)){ - processSourcesAndNonManoSources(iterator, iterator.next()); - }else if(prevLine.startsWith(CMS_BEGIN)){ - String line = iterator.next(); - while(iterator.hasNext() && !line.contains(CMD_END)){ - line = iterator.next(); + } + return Optional.empty(); + } + + /** + * Validates the manifest metadata content, reporting errors found. + * + * @return {@code true} if the metadata content is valid, {@code false} otherwise. + */ + private boolean validateMetadata() { + if (metadata.isEmpty()) { + reportError(Messages.MANIFEST_NO_METADATA); + return false; + } + + final Entry<String, String> firstManifestEntry = metadata.entrySet().iterator().next(); + final ManifestTokenType firstManifestEntryTokenType = + ManifestTokenType.parse(firstManifestEntry.getKey()).orElse(null); + if (firstManifestEntryTokenType == null) { + reportError(Messages.MANIFEST_METADATA_INVALID_ENTRY1, firstManifestEntry.getKey()); + return false; + } + for (final Entry<String, String> manifestEntry : metadata.entrySet()) { + final ManifestTokenType manifestEntryTokenType = ManifestTokenType.parse(manifestEntry.getKey()) + .orElse(null); + if (manifestEntryTokenType == null) { + reportError(Messages.MANIFEST_METADATA_INVALID_ENTRY1, manifestEntry.getKey()); + return false; + } + if ((firstManifestEntryTokenType.isMetadataVnfEntry() && !manifestEntryTokenType.isMetadataVnfEntry()) + || (firstManifestEntryTokenType.isMetadataPnfEntry() && !manifestEntryTokenType.isMetadataPnfEntry())) { + reportError(Messages.MANIFEST_METADATA_UNEXPECTED_ENTRY_TYPE); + return false; } - processSourcesAndNonManoSources(iterator, iterator.next()); } - else if(prevLine.startsWith(NON_MANO_MF_ATTRIBUTE+ SEPARATOR_MF_ATTRIBUTE)){ - //non mano should be the last bit in manifest file, - // all sources after non mano will be placed to the last non mano - // key, if any other structure met error reported - processNonManoInputs(iterator, iterator.next()); - }else{ - reportError(prevLine); + + if (metadata.entrySet().size() != MAX_ALLOWED_MANIFEST_META_ENTRIES) { + reportError(Messages.MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT, MAX_ALLOWED_MANIFEST_META_ENTRIES); + return false; } + + return true; } - private void processSource(Iterator<String> iterator, String prevLine) { - String value = prevLine.substring((SOURCE_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE).length()).trim(); - sources.add(value); - if(iterator.hasNext()) { - processSourcesAndNonManoSources(iterator, iterator.next()); + /** + * Processes a Manifest {@link ManifestTokenType#SOURCE} entry. + */ + private void processSource() { + final Optional<String> currentLine = getCurrentLine(); + if (!currentLine.isPresent()) { + return; + } + final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null); + if (manifestTokenType != ManifestTokenType.SOURCE) { + return; + } + + final String sourceLine = currentLine.get(); + final String sourcePath = readEntryValue(sourceLine).orElse(null); + + if (sourcePath == null) { + reportError(Messages.MANIFEST_EXPECTED_SOURCE_PATH); + return; } + sources.add(sourcePath); + readAlgorithmEntry(sourcePath); } - private void processNonManoInputs(Iterator<String> iterator, String prevLine) { - if(prevLine.trim().equals(SOURCE_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE)){ - reportError(prevLine); + /** + * Processes entries {@link ManifestTokenType#ALGORITHM} and {@link ManifestTokenType#HASH} of a {@link + * ManifestTokenType#SOURCE} entry. + * + * @param sourcePath the source path related to the algorithm entry. + */ + private void readAlgorithmEntry(final String sourcePath) { + Optional<String> currentLine = readNextNonEmptyLine(); + if (!currentLine.isPresent()) { return; } - if(!prevLine.contains(SEPARATOR_MF_ATTRIBUTE)){ - reportError(prevLine); + final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null); + if (manifestTokenType == ManifestTokenType.HASH) { + reportError(Messages.MANIFEST_EXPECTED_ALGORITHM_BEFORE_HASH); + continueToProcess = false; return; } - - String[] metaSplit = prevLine.trim().split(SEPARATOR_MF_ATTRIBUTE); - if (metaSplit.length > 1){ - reportError(prevLine); + if (manifestTokenType != ManifestTokenType.ALGORITHM) { return; } - int index = prevLine.indexOf(':'); - if(index > 0){ - prevLine = prevLine.substring(0, index); + final String algorithmLine = currentLine.get(); + final String algorithmType = readEntryValue(algorithmLine).orElse(null); + if (algorithmType == null) { + reportError(Messages.MANIFEST_EXPECTED_ALGORITHM_VALUE); + continueToProcess = false; + return; } - processNonManoSource(iterator, prevLine, new ArrayList<>()); - } + currentLine = readNextNonEmptyLine(); + if (!currentLine.isPresent() || detectLineEntry().orElse(null) != ManifestTokenType.HASH) { + reportError(Messages.MANIFEST_EXPECTED_HASH_ENTRY); + continueToProcess = false; + return; + } - private void processNonManoSource(Iterator<String> iterator, String key, List<String> sources) { - if(!iterator.hasNext()){ + final String hashLine = currentLine.get(); + final String hash = readEntryValue(hashLine).orElse(null); + if (hash == null) { + reportError(Messages.MANIFEST_EXPECTED_HASH_VALUE); + continueToProcess = false; return; } - String line = iterator.next(); - if(line.isEmpty()){ - processNonManoSource(iterator, key, sources); - }else if(line.trim().startsWith(SOURCE_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE)){ - String value = line.replace(SOURCE_MF_ATTRIBUTE + SEPARATOR_MF_ATTRIBUTE, "").trim(); - sources.add(value); - processNonManoSource(iterator, key, sources); - }else { - processNonManoInputs(iterator, line); - } - nonManoSources.put(key.trim(), sources); + sourceAndChecksumMap.put(sourcePath, new AlgorithmDigest(algorithmType, hash)); + readNextNonEmptyLine(); } + }
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/ManifestParsingTest.java b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/ManifestParsingTest.java deleted file mode 100644 index b083cfad3a..0000000000 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/ManifestParsingTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openecomp.sdc.tosca.csar; - -import org.junit.Before; -import org.junit.Test; -import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; -import org.openecomp.sdc.common.errors.Messages; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; - -import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - - -public class ManifestParsingTest { - - private Manifest manifest; - - @Before - public void setUp(){ - manifest = new SOL004ManifestOnboarding(); - } - - @Test - public void testSuccessfulParsing() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/ValidTosca.mf")) { - manifest.parse(is); - assertTrue(manifest.isValid()); - assertEquals(manifest.getMetadata().size(), 4); - assertEquals(manifest.getSources().size(), 5); - Optional<ResourceTypeEnum> resourceTypeEnum = manifest.getType(); - if(resourceTypeEnum.isPresent()){ - assertTrue(resourceTypeEnum.get() == ResourceTypeEnum.VF); - } - } - } - - @Test - public void testNoMetadataParsing() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca1.mf")) { - manifest.parse(is); - assertFalse(manifest.isValid()); - assertTrue(manifest.getErrors().stream().anyMatch(error -> error - .contains(Messages.MANIFEST_INVALID_LINE.getErrorMessage().substring(0, 10)))); - } - } - - @Test - public void testBrokenMDParsing() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca2.mf")) { - manifest.parse(is); - assertFalse(manifest.isValid()); - assertTrue(manifest.getErrors().stream().anyMatch(error -> error - .contains(Messages.MANIFEST_INVALID_LINE.getErrorMessage().substring(0, 10)))); - } - } - - @Test - public void testNoMetaParsing() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca4.mf")) { - manifest.parse(is); - assertFalse(manifest.isValid()); - assertTrue(manifest.getErrors().stream().anyMatch(error -> error - .contains(Messages.MANIFEST_NO_METADATA.getErrorMessage().substring(0, 10)))); - } - } - - @Test - public void testSuccessfulNonManoParsing() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/ValidNonManoTosca.mf")) { - manifest.parse(is); - assertTrue(manifest.isValid()); - assertEquals(manifest.getMetadata().size(), 4); - assertEquals(manifest.getSources().size(), 5); - assertEquals(manifest.getNonManoSources().size(), 2); - } - } - - @Test - public void testFailfulNonManoParsing() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/InValidNonManoTosca.mf")) { - manifest.parse(is); - assertFalse(manifest.isValid()); - } - } - - @Test - public void testFailfulNonManoParsingWithGarbadge() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/InvalidTocsaNonManoGarbadgeAtEnd.mf")) { - manifest.parse(is); - assertFalse(manifest.isValid()); - } - } - - @Test - public void testParseManifestWithNoFile() throws IOException { - try (InputStream is = getClass() - .getResourceAsStream("/vspmanager.csar/manifest/SOME_WRONG_FILE")) { - manifest.parse(is); - assertFalse(manifest.isValid()); - } - } -} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboardingTest.java b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboardingTest.java new file mode 100644 index 0000000000..7cb1511a32 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboardingTest.java @@ -0,0 +1,436 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.tosca.csar; + +import static junit.framework.TestCase.assertSame; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.common.errors.Messages; + +public class SOL004ManifestOnboardingTest { + + private Manifest manifest; + + @Before + public void setUp() { + manifest = new SOL004ManifestOnboarding(); + } + + @Test + public void testSuccessfulParsing() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/ValidTosca.mf")) { + manifest.parse(manifestAsStream); + assertValidManifest(4, 5, Collections.emptyMap(), ResourceTypeEnum.VF); + } + } + + @Test + public void testNoMetadataParsing() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/invalid/no-metadata.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(3, "Source: MainServiceTemplate.yaml", Messages.MANIFEST_START_METADATA) + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testBrokenMDParsing() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca2.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(Messages.MANIFEST_INVALID_LINE.formatMessage(9, "vnf_package_version: 1.0")); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testNoMetaParsing() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-metadata-with-source.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(4, "Source: MainServiceTemplate.yaml", + Messages.MANIFEST_METADATA_INVALID_ENTRY1, "Source: MainServiceTemplate.yaml") + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testSuccessfulNonManoParsing() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/ValidNonManoTosca.mf")) { + manifest.parse(manifestAsStream); + assertValidManifest(4, 5, + ImmutableMap.of("foo_bar", 3, "prv.happy-nfv.cool", 3), ResourceTypeEnum.VF); + } + } + + @Test + public void testInvalidNonManoParsing() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/InValidNonManoTosca.mf")) { + manifest.parse(manifestAsStream); + final List<String> errorList = Collections.singletonList( + buildErrorMessage(34, "vnf_product_name: Mock", Messages.MANIFEST_INVALID_NON_MANO_KEY, + "vnf_product_name") + ); + assertInvalidManifest(errorList); + } + } + + private String buildErrorMessage(final int lineNumber, final String line, final Messages message, + final Object... params) { + return Messages.MANIFEST_ERROR_WITH_LINE.formatMessage(message.formatMessage(params), lineNumber, line); + } + + @Test + public void testNonManoParsingWithGarbage() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/InvalidToscaNonManoGarbageAtEnd.mf")) { + manifest.parse(manifestAsStream); + final List<String> errorList = Collections.singletonList( + Messages.MANIFEST_ERROR_WITH_LINE.formatMessage( + Messages.MANIFEST_INVALID_NON_MANO_KEY.formatMessage("some garbage"), + 34, "some garbage") + ); + assertInvalidManifest(errorList); + } + } + + @Test + public void testInvalidManifestFile() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/SOME_WRONG_FILE")) { + manifest.parse(manifestAsStream); + assertInvalidManifest(Collections.singletonList(Messages.MANIFEST_PARSER_INTERNAL.getErrorMessage())); + } + } + + @Test + public void testManifestSigned() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/valid/signed.mf")) { + manifest.parse(manifestAsStream); + assertValidManifest(4, 3, Collections.emptyMap(), ResourceTypeEnum.VF); + } + } + + @Test + public void testManifestSignedWithNonManoArtifacts() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/valid/signed-with-non-mano.mf")) { + manifest.parse(manifestAsStream); + assertValidManifest(4, 3, ImmutableMap.of("foo_bar", 3), ResourceTypeEnum.VF); + manifest.getType().ifPresent(typeEnum -> assertSame(typeEnum, ResourceTypeEnum.VF)); + } + } + + @Test + public void testManifestWithPnf() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/valid/metadata-pnfd.mf")) { + manifest.parse(manifestAsStream); + assertValidManifest(4, 3, new HashMap<>(), ResourceTypeEnum.PNF); + } + } + + @Test + public void testMetadataWithNoValue() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-no-value.mf")) { + manifest.parse(manifestAsStream); + + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(3, "vnf_provider_id", Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_provider_id") + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testMetadataWithValueButNoEntry() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-no-entry.mf")) { + manifest.parse(manifestAsStream); + + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(3, ": no-entry-value", Messages.MANIFEST_METADATA_INVALID_ENTRY1, ": no-entry-value") + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testMetadataWithIncorrectEntry() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(4, "vnf_release_data_time: 2019-08-29T22:17:39.275281", + Messages.MANIFEST_METADATA_INVALID_ENTRY1, "vnf_release_data_time: 2019-08-29T22:17:39.275281") + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testMetadataWithMixedEntries() throws IOException { + try (final InputStream manifestAsStream = getClass() + .getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(buildErrorMessage(6, "", Messages.MANIFEST_METADATA_UNEXPECTED_ENTRY_TYPE)); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testMetadataWithDuplicatedEntries() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(4, "vnf_product_name: vPP", Messages.MANIFEST_METADATA_DUPLICATED_ENTRY, + "vnf_product_name") + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestNonManoKeyWithoutSources() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(11, "", Messages.MANIFEST_EMPTY_NON_MANO_KEY, + "foo_bar") + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestNonManoKeyWithEmptySourceEntry() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add( + buildErrorMessage(11, "Source:", Messages.MANIFEST_EMPTY_NON_MANO_SOURCE) + ); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestWithEmptyMetadata() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-metadata.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(buildErrorMessage(2, "", Messages.MANIFEST_NO_METADATA)); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestSourceAlgorithmWithoutHash() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(buildErrorMessage(9, "", Messages.MANIFEST_EXPECTED_HASH_ENTRY)); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestSourceHashWithoutAlgorithm() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(buildErrorMessage(8, "Hash: 3b119b37da5b76ec7c933168b21cedd8", Messages.MANIFEST_EXPECTED_ALGORITHM_BEFORE_HASH)); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestSourceAlgorithmWithoutValue() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(buildErrorMessage(8, "Algorithm:", Messages.MANIFEST_EXPECTED_ALGORITHM_VALUE)); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestSourceHashWithoutValue() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/source-hash-without-value.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(buildErrorMessage(9, "Hash:", Messages.MANIFEST_EXPECTED_HASH_VALUE)); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testEmptyManifest() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/empty-manifest.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(Messages.MANIFEST_EMPTY.getErrorMessage()); + assertInvalidManifest(expectedErrorList); + } + } + + @Test + public void testManifestWithDuplicatedCmsSignature() throws IOException { + try (final InputStream manifestAsStream = + getClass().getResourceAsStream("/vspmanager.csar/manifest/invalid/double-signed.mf")) { + manifest.parse(manifestAsStream); + final List<String> expectedErrorList = new ArrayList<>(); + expectedErrorList + .add(buildErrorMessage(26, "-----BEGIN CMS-----", Messages.MANIFEST_DUPLICATED_CMS_SIGNATURE)); + assertInvalidManifest(expectedErrorList); + } + } + + + @Test + public void testGetEntry() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + final Method getEntryMethod = AbstractOnboardingManifest.class.getDeclaredMethod("readEntryName", String.class); + getEntryMethod.setAccessible(true); + final Optional<String> noEntry = (Optional<String>) getEntryMethod.invoke(manifest, ":"); + assertThat("Entry should not be present", noEntry.isPresent(), is(false)); + + final Optional<String> blankEntry = (Optional<String>) getEntryMethod.invoke(manifest, " :"); + assertThat("Entry should not be present", blankEntry.isPresent(), is(false)); + + final Optional<String> noColon = (Optional<String>) getEntryMethod.invoke(manifest, "anyKeyWithoutColon "); + assertThat("Entry should not be present", noColon.isPresent(), is(false)); + + final Optional<String> blank = (Optional<String>) getEntryMethod.invoke(manifest, " "); + assertThat("Entry should not be present", blank.isPresent(), is(false)); + + final Optional<String> empty = (Optional<String>) getEntryMethod.invoke(manifest, ""); + assertThat("Entry should not be present", empty.isPresent(), is(false)); + + final Optional<String> nul1 = (Optional<String>) getEntryMethod.invoke(manifest, new Object[]{null}); + assertThat("Entry should not be present", nul1.isPresent(), is(false)); + + final Optional<String> entry = (Optional<String>) getEntryMethod + .invoke(manifest, " entry to test : : a value ::: test test: "); + assertThat("Entry should be present", entry.isPresent(), is(true)); + assertThat("Entry should be as expected", entry.get(), equalTo("entry to test")); + } + + @Test + public void testGetValue() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + final Method getValueMethod = AbstractOnboardingManifest.class.getDeclaredMethod("readEntryValue", String.class); + getValueMethod.setAccessible(true); + final Optional<String> noValue = (Optional<String>) getValueMethod.invoke(manifest, ":"); + assertThat("Value should not be present", noValue.isPresent(), is(false)); + + final Optional<String> blankValue = (Optional<String>) getValueMethod.invoke(manifest, ": "); + assertThat("Value should not be present", blankValue.isPresent(), is(false)); + + final Optional<String> noColon = (Optional<String>) getValueMethod.invoke(manifest, "anyKeyWithoutColon "); + assertThat("Value should not be present", noColon.isPresent(), is(false)); + + final Optional<String> blank = (Optional<String>) getValueMethod.invoke(manifest, " "); + assertThat("Value should not be present", blank.isPresent(), is(false)); + + final Optional<String> empty = (Optional<String>) getValueMethod.invoke(manifest, ""); + assertThat("Value should not be present", empty.isPresent(), is(false)); + + final Optional<String> nul1 = (Optional<String>) getValueMethod.invoke(manifest, new Object[]{null}); + assertThat("Value should not be present", nul1.isPresent(), is(false)); + + final Optional<String> value = (Optional<String>) getValueMethod + .invoke(manifest, "attribute : : a value ::: test test: "); + assertThat("Value should be present", value.isPresent(), is(true)); + assertThat("Value should be as expected", value.get(), equalTo(": a value ::: test test:")); + } + + private void assertValidManifest(final int expectedMetadataSize, final int expectedSourcesSize, + final Map<String, Integer> expectedNonManoKeySize, + final ResourceTypeEnum resourceType) { + assertThat("Should have no errors", manifest.getErrors(), is(empty())); + assertThat("Should be valid", manifest.isValid(), is(true)); + assertThat("Metadata should have the expected size", + manifest.getMetadata().keySet(), hasSize(expectedMetadataSize)); + assertThat("Sources should have the expected size", manifest.getSources(), hasSize(expectedSourcesSize)); + assertThat("Non Mano Sources keys should have the expected size", + manifest.getNonManoSources().keySet(), hasSize(expectedNonManoKeySize.keySet().size())); + for (final Entry<String, Integer> nonManoKeyAndSize : expectedNonManoKeySize.entrySet()) { + final String nonManoKey = nonManoKeyAndSize.getKey(); + assertThat("Should contain expected Non Mano Sources key", + manifest.getNonManoSources().keySet(), hasItem(nonManoKey)); + assertThat(String.format("Non Mano Sources keys %s should have the expected sources size", nonManoKey), + manifest.getNonManoSources().get(nonManoKey).size(), equalTo(nonManoKeyAndSize.getValue())); + } + assertThat("Should have a type", manifest.getType().isPresent(), is(true)); + assertThat("Type should be as expected", manifest.getType().get(), equalTo(resourceType)); + } + + private void assertInvalidManifest(final List<String> expectedErrorList) { + assertThat("Should be invalid", manifest.isValid(), is(false)); + assertThat("Should have the expected error quantity", manifest.getErrors(), hasSize(expectedErrorList.size())); + assertThat("Should have expected errors", manifest.getErrors(), + containsInAnyOrder(expectedErrorList.toArray(new String[0]))); + } +} diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InValidNonManoTosca.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InValidNonManoTosca.mf index 9cced6b371..02215a6cfb 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InValidNonManoTosca.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InValidNonManoTosca.mf @@ -2,7 +2,7 @@ metadata: vnf_product_name: Mock vnf_provider_id: ZTE vnf_package_version: 1.0 - vnf_release_data_time: 2017.01.01T10:00+03:00 + vnf_release_date_time: 2017.01.01T10:00+03:00 Source: MainServiceTemplate.yaml diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca2.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca2.mf index 057f54867b..54bb5cd65f 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca2.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca2.mf @@ -1,11 +1,13 @@ metadata: vnf_product_name: Mock vnf_provider_id: ZTE + vnf_package_version: 1.0 + vnf_release_date_time: 2017.01.01T10:00+03:00 Source: MainServiceTemplate.yaml vnf_package_version: 1.0 - vnf_release_data_time: 2017.01.01T10:00+03:00 + vnf_release_date_time: 2017.01.01T10:00+03:00 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca3.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca3.mf index 64e9445f7f..060207f120 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca3.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca3.mf @@ -2,6 +2,6 @@ metadata: vnf_product_name: Mock vnf_provider_id: ZTE vnf_package_version: 1.0 - vnf_release_data_time: 2017.01.01T10:00+03:00 + vnf_release_date_time: 2017.01.01T10:00+03:00 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTocsaNonManoGarbadgeAtEnd.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidToscaNonManoGarbageAtEnd.mf index cfe6bc48da..15c2833c22 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTocsaNonManoGarbadgeAtEnd.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidToscaNonManoGarbageAtEnd.mf @@ -2,7 +2,7 @@ metadata: vnf_product_name: Mock vnf_provider_id: ZTE vnf_package_version: 1.0 - vnf_release_data_time: 2017.01.01T10:00+03:00 + vnf_release_date_time: 2017.01.01T10:00+03:00 Source: MainServiceTemplate.yaml @@ -31,4 +31,4 @@ non_mano_artifact_sets: Source: happy/cool/hot/hot_or_cool.json -some garbadge
\ No newline at end of file +some garbage
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidNonManoTosca.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidNonManoTosca.mf index 25ec14c7cc..03f2b3cf3b 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidNonManoTosca.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidNonManoTosca.mf @@ -2,7 +2,7 @@ metadata: vnf_product_name: Mock vnf_provider_id: ZTE vnf_package_version: 1.0 - vnf_release_data_time: 2017.01.01T10:00+03:00 + vnf_release_date_time: 2017.01.01T10:00+03:00 Source: MainServiceTemplate.yaml diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidTosca.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidTosca.mf index b2accb7a1c..b9d3844d53 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidTosca.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidTosca.mf @@ -2,7 +2,7 @@ metadata: vnf_product_name: Mock vnf_provider_id: ZTE vnf_package_version: 1.0 - vnf_release_data_time: 2017.01.01T10:00+03:00 + vnf_release_date_time: 2017.01.01T10:00+03:00 Source: MainServiceTemplate.yaml diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/double-signed.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/double-signed.mf new file mode 100644 index 0000000000..88098a1006 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/double-signed.mf @@ -0,0 +1,35 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file +Algorithm: md5 +Hash: 3b119b37da5b76ec7c933168b21cedd8 + +-----BEGIN CMS----- +MIIBcwYJKoZIhvcNAQcCoIIBZDCCAWACAQMxDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBMYIBPTCCATkCAQOAFGOGMKMvLSRzUBjkgZipSoZm1U/UMAsGCWCGSAFl +AwQCATANBgkqhkiG9w0BAQEFAASCAQBNHXz1p5NBM9Nlvp8RPoVjszzh9UfQ/OCp +mB926MTLexWOiawjPRKuoiXn4y4dQFZBXauunCOyXYfPASUMFnhL/7gvhajPH25/ +MwEyEsUqsCyJ63tAeYxZAqTZWA2pZi9ejCPoRnt6xl7EhEyogXiSBgc2P89hxhe6 +0/MP6Mtw9D8Ks7M1LxH6ntxGApPTNRlmMtQkrx/ZUtAcKKZJoNpofzdmd+O60PMT +igNsuwzMNy5LfSjvp8xgWoxhWr4/zLRIZ5F5Z5qhz7lia9xDSGYMfPitDCVqI9XE +O58S/FoHu+z3Tig7vauTFFbiJjIu9SkG0c33ayEUCKejuVQPjuY9 +-----END CMS----- + +Source: scripts/userdata.file.sm +Algorithm: md5 +Hash: 3b119b37da5b76ec7c933168b21cedd7 + +-----BEGIN CMS----- +MIIBcwYJKoZIhvcNAQcCoIIBZDCCAWACAQMxDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBMYIBPTCCATkCAQOAFGOGMKMvLSRzUBjkgZipSoZm1U/UMAsGCWCGSAFl +AwQCATANBgkqhkiG9w0BAQEFAASCAQBNHXz1p5NBM9Nlvp8RPoVjszzh9UfQ/OCp +mB926MTLexWOiawjPRKuoiXn4y4dQFZBXauunCOyXYfPASUMFnhL/7gvhajPH25/ +MwEyEsUqsCyJ63tAeYxZAqTZWA2pZi9ejCPoRnt6xl7EhEyogXiSBgc2P89hxhe6 +0/MP6Mtw9D8Ks7M1LxH6ntxGApPTNRlmMtQkrx/ZUtAcKKZJoNpofzdmd+O60PMT +igNsuwzMNy5LfSjvp8xgWoxhWr4/zLRIZ5F5Z5qhz7lia9xDSGYMfPitDCVqI9XE +O58S/FoHu+z3Tig7vauTFFbiJjIu9SkG0c33ayEUCKejuVQPjuY9 +-----END CMS----- diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-manifest.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-manifest.mf new file mode 100644 index 0000000000..3f2ff2d6cc --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-manifest.mf @@ -0,0 +1,5 @@ + + + + + diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca4.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata-with-source.mf index d8e291c4a3..d8e291c4a3 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca4.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata-with-source.mf diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata.mf new file mode 100644 index 0000000000..7b518cbe81 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata.mf @@ -0,0 +1 @@ +metadata:
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf new file mode 100644 index 0000000000..696265eab1 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf @@ -0,0 +1,4 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_product_name: vPP diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf new file mode 100644 index 0000000000..139e18e267 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf @@ -0,0 +1,5 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_release_data_time: 2019-08-29T22:17:39.275281 + vnf_package_version: R24A583 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf new file mode 100644 index 0000000000..0d26e2de98 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf @@ -0,0 +1,5 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_release_date_time: 2019-08-29T22:17:39.275281 + pnfd_archive_version: 1.0 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-entry.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-entry.mf new file mode 100644 index 0000000000..bc6db7ebf4 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-entry.mf @@ -0,0 +1,3 @@ +metadata: + vnf_product_name: vPP + : no-entry-value
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-value.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-value.mf new file mode 100644 index 0000000000..9d286d6dd9 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-value.mf @@ -0,0 +1,3 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca1.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/no-metadata.mf index ebdec213d3..ebdec213d3 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca1.mf +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/no-metadata.mf diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf new file mode 100644 index 0000000000..e4544d487a --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf @@ -0,0 +1,11 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file.sm + +non_mano_artifact_sets: + foo_bar: + Source:
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf new file mode 100644 index 0000000000..a7533bbf45 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf @@ -0,0 +1,10 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file.sm + +non_mano_artifact_sets: + foo_bar: diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf new file mode 100644 index 0000000000..a9a988735b --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf @@ -0,0 +1,8 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file.sm +Algorithm: md5 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf new file mode 100644 index 0000000000..79797d7b8c --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf @@ -0,0 +1,9 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file.sm +Algorithm: +Hash: 3b119b37da5b76ec7c933168b21cedd8 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf new file mode 100644 index 0000000000..ec10bc800f --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf @@ -0,0 +1,8 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file.sm +Hash: 3b119b37da5b76ec7c933168b21cedd8 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-value.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-value.mf new file mode 100644 index 0000000000..2d786f1e54 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-value.mf @@ -0,0 +1,9 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: scripts/userdata.file.sm +Algorithm: md5 +Hash: diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/metadata-pnfd.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/metadata-pnfd.mf new file mode 100644 index 0000000000..8bf73ede63 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/metadata-pnfd.mf @@ -0,0 +1,27 @@ +metadata: + pnfd_name: Name + pnfd_provider: Provider + pnfd_archive_version: 1.0 + pnfd_release_date_time: 2017-01-01T10:00:00+03:00 + +Source: TOSCA-Metadata/TOSCA.meta + +Source: scripts/userdata.file +Algorithm: md5 +Hash: 3b119b37da5b76ec7c933168b21cedd8 + +Source: scripts/userdata.file.sm + + + + +-----BEGIN CMS----- +MIIBcwYJKoZIhvcNAQcCoIIBZDCCAWACAQMxDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBMYIBPTCCATkCAQOAFGOGMKMvLSRzUBjkgZipSoZm1U/UMAsGCWCGSAFl +AwQCATANBgkqhkiG9w0BAQEFAASCAQBNHXz1p5NBM9Nlvp8RPoVjszzh9UfQ/OCp +mB926MTLexWOiawjPRKuoiXn4y4dQFZBXauunCOyXYfPASUMFnhL/7gvhajPH25/ +MwEyEsUqsCyJ63tAeYxZAqTZWA2pZi9ejCPoRnt6xl7EhEyogXiSBgc2P89hxhe6 +0/MP6Mtw9D8Ks7M1LxH6ntxGApPTNRlmMtQkrx/ZUtAcKKZJoNpofzdmd+O60PMT +igNsuwzMNy5LfSjvp8xgWoxhWr4/zLRIZ5F5Z5qhz7lia9xDSGYMfPitDCVqI9XE +O58S/FoHu+z3Tig7vauTFFbiJjIu9SkG0c33ayEUCKejuVQPjuY9 +-----END CMS----- diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed-with-non-mano.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed-with-non-mano.mf new file mode 100644 index 0000000000..dee6384892 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed-with-non-mano.mf @@ -0,0 +1,30 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: TOSCA-Metadata/TOSCA.meta + +Source: scripts/userdata.file +Algorithm: md5 +Hash: 3b119b37da5b76ec7c933168b21cedd8 + +Source: scripts/userdata.file.sm + +-----BEGIN CMS----- +MIIBcwYJKoZIhvcNAQcCoIIBZDCCAWACAQMxDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBMYIBPTCCATkCAQOAFGOGMKMvLSRzUBjkgZipSoZm1U/UMAsGCWCGSAFl +AwQCATANBgkqhkiG9w0BAQEFAASCAQBNHXz1p5NBM9Nlvp8RPoVjszzh9UfQ/OCp +mB926MTLexWOiawjPRKuoiXn4y4dQFZBXauunCOyXYfPASUMFnhL/7gvhajPH25/ +MwEyEsUqsCyJ63tAeYxZAqTZWA2pZi9ejCPoRnt6xl7EhEyogXiSBgc2P89hxhe6 +0/MP6Mtw9D8Ks7M1LxH6ntxGApPTNRlmMtQkrx/ZUtAcKKZJoNpofzdmd+O60PMT +igNsuwzMNy5LfSjvp8xgWoxhWr4/zLRIZ5F5Z5qhz7lia9xDSGYMfPitDCVqI9XE +O58S/FoHu+z3Tig7vauTFFbiJjIu9SkG0c33ayEUCKejuVQPjuY9 +-----END CMS----- + +non_mano_artifact_sets: + foo_bar: + Source: foobar/foo/foo.yaml + Source: foobar/foo/foo.script + Source: foobar/bar/descriptor.xml diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed.mf b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed.mf new file mode 100644 index 0000000000..fe43239d29 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed.mf @@ -0,0 +1,27 @@ +metadata: + vnf_product_name: vPP + vnf_provider_id: Ericsson + vnf_package_version: R24A583 + vnf_release_date_time: 2019-08-29T22:17:39.275281 + +Source: TOSCA-Metadata/TOSCA.meta + +Source: scripts/userdata.file +Algorithm: md5 +Hash: 3b119b37da5b76ec7c933168b21cedd8 + +Source: scripts/userdata.file.sm + + + + +-----BEGIN CMS----- +MIIBcwYJKoZIhvcNAQcCoIIBZDCCAWACAQMxDTALBglghkgBZQMEAgEwCwYJKoZI +hvcNAQcBMYIBPTCCATkCAQOAFGOGMKMvLSRzUBjkgZipSoZm1U/UMAsGCWCGSAFl +AwQCATANBgkqhkiG9w0BAQEFAASCAQBNHXz1p5NBM9Nlvp8RPoVjszzh9UfQ/OCp +mB926MTLexWOiawjPRKuoiXn4y4dQFZBXauunCOyXYfPASUMFnhL/7gvhajPH25/ +MwEyEsUqsCyJ63tAeYxZAqTZWA2pZi9ejCPoRnt6xl7EhEyogXiSBgc2P89hxhe6 +0/MP6Mtw9D8Ks7M1LxH6ntxGApPTNRlmMtQkrx/ZUtAcKKZJoNpofzdmd+O60PMT +igNsuwzMNy5LfSjvp8xgWoxhWr4/zLRIZ5F5Z5qhz7lia9xDSGYMfPitDCVqI9XE +O58S/FoHu+z3Tig7vauTFFbiJjIu9SkG0c33ayEUCKejuVQPjuY9 +-----END CMS----- |