summaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-tosca-lib
diff options
context:
space:
mode:
authorandre.schmid <andre.schmid@est.tech>2019-08-30 18:20:32 +0100
committerOren Kleks <orenkle@amdocs.com>2019-10-24 06:15:28 +0000
commit78f88751aa64fb72fd6321346929bd1d94f716a9 (patch)
tree58cabd13dcfbad357729ef338c8e2dca3255f1fb /openecomp-be/lib/openecomp-tosca-lib
parent105ce0729d5333cc095ef5bd8104a6c5b90cc9f0 (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>
Diffstat (limited to 'openecomp-be/lib/openecomp-tosca-lib')
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/pom.xml12
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AbstractOnboardingManifest.java397
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/AlgorithmDigest.java33
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/CSARConstants.java36
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/Manifest.java16
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ManifestTokenType.java84
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/ONAPManifestOnboarding.java58
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingToscaMetadata.java6
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboarding.java331
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/ManifestParsingTest.java127
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/java/org/openecomp/sdc/tosca/csar/SOL004ManifestOnboardingTest.java436
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InValidNonManoTosca.mf2
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca2.mf4
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca3.mf2
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidToscaNonManoGarbageAtEnd.mf (renamed from openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTocsaNonManoGarbadgeAtEnd.mf)4
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidNonManoTosca.mf2
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/ValidTosca.mf2
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/double-signed.mf35
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-manifest.mf5
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata-with-source.mf (renamed from openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca4.mf)0
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/empty-metadata.mf1
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-duplicated-entries.mf4
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-incorrect-entry.mf5
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-mixed-entries.mf5
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-entry.mf3
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/metadata-no-value.mf3
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/no-metadata.mf (renamed from openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/InvalidTosca1.mf)0
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-empty-source.mf11
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/non-mano-key-with-no-sources.mf10
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-hash.mf8
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-algorithm-without-value.mf9
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-algorithm.mf8
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/invalid/source-hash-without-value.mf9
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/metadata-pnfd.mf27
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed-with-non-mano.mf30
-rw-r--r--openecomp-be/lib/openecomp-tosca-lib/src/test/resources/vspmanager.csar/manifest/valid/signed.mf27
36 files changed, 1398 insertions, 354 deletions
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-----