summaryrefslogtreecommitdiffstats
path: root/csarvalidation/src/main/java/org/onap
diff options
context:
space:
mode:
authorvasraz <vasyl.razinkov@est.tech>2019-12-12 14:41:10 +0000
committervasraz <vasyl.razinkov@est.tech>2019-12-13 10:28:21 +0000
commit02cd70328143803d94912634eab0afe378764ed1 (patch)
tree9128937d0301a971a0c939995521f2f0efcfa60c /csarvalidation/src/main/java/org/onap
parent8db4db6563a98c4fac3e833707ab2b14098657d5 (diff)
Implement PNF package validation on PNF software version
1. New requirement (R-972082) 2. Edit requirement (R-146092) 3. Remove unused dependencies. Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech> Change-Id: I0518da5cdbf22b0086cf2c4f50194b47994273f7 Issue-ID: VNFSDK-531
Diffstat (limited to 'csarvalidation/src/main/java/org/onap')
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java76
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR146092.java148
-rw-r--r--csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR972082.java320
3 files changed, 441 insertions, 103 deletions
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java
index 701c524..fefe65b 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR130206.java
@@ -54,8 +54,8 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
private final ShaHashCodeGenerator shaHashCodeGenerator = new ShaHashCodeGenerator();
private final ManifestFileSignatureValidator manifestFileSignatureValidator = new ManifestFileSignatureValidator();
-
public static class CSARErrorUnableToFindCertificate extends CSARArchive.CSARError {
+
CSARErrorUnableToFindCertificate(String paramName) {
super("0x4001");
this.message = String.format("Unable to find cert file defined by %s!", paramName);
@@ -63,6 +63,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorUnableToFindCmsSection extends CSARArchive.CSARError {
+
CSARErrorUnableToFindCmsSection() {
super("0x4002");
this.message = "Unable to find CMS section in manifest!";
@@ -70,6 +71,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorUnableToFindCsarContent extends CSARArchive.CSARError {
+
CSARErrorUnableToFindCsarContent() {
super("0x4003");
this.message = "Unable to find csar content!";
@@ -77,6 +79,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorWrongHashCode extends CSARArchive.CSARError {
+
CSARErrorWrongHashCode(String path) {
super("0x4004");
this.message = String.format("Source '%s' has wrong hash!", path);
@@ -84,6 +87,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorUnableToFindAlgorithm extends CSARArchive.CSARError {
+
CSARErrorUnableToFindAlgorithm(String path) {
super("0x4005");
this.message = String.format("Source '%s' has hash, but unable to find algorithm tag!", path);
@@ -91,6 +95,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorUnableToFindSource extends CSARArchive.CSARError {
+
CSARErrorUnableToFindSource(String path) {
super("0x4006");
this.message = String.format("Unable to calculate digest - file missing: %s", path);
@@ -98,6 +103,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorInvalidSignature extends CSARArchive.CSARError {
+
CSARErrorInvalidSignature() {
super("0x4007");
this.message = "File has invalid CMS signature!";
@@ -105,6 +111,7 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
public static class CSARErrorContentMismatch extends CSARArchive.CSARError {
+
CSARErrorContentMismatch() {
super("0x4008");
this.message = "Mismatch between contents of non-mano-artifact-sets and source files of the package";
@@ -146,21 +153,22 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
}
- private void validateNonManoCohesionWithSources(final Map<String, Map<String, List<String>>> nonMano, final List<SourcesParser.Source> sources) {
+ private void validateNonManoCohesionWithSources(final Map<String, Map<String, List<String>>> nonMano,
+ final List<SourcesParser.Source> sources) {
final Collection<Map<String, List<String>>> values = nonMano.values();
final List<String> nonManoSourcePaths = values.stream()
- .map(Map::values)
- .flatMap(Collection::stream)
- .flatMap(List::stream)
- .filter(it -> !it.isEmpty())
- .collect(Collectors.toList());
+ .map(Map::values)
+ .flatMap(Collection::stream)
+ .flatMap(List::stream)
+ .filter(it -> !it.isEmpty())
+ .collect(Collectors.toList());
final List<String> sourcePaths = sources.stream()
- .map(SourcesParser.Source::getValue)
- .collect(Collectors.toList());
+ .map(SourcesParser.Source::getValue)
+ .collect(Collectors.toList());
- if(!sourcePaths.containsAll(nonManoSourcePaths)){
+ if (!sourcePaths.containsAll(nonManoSourcePaths)) {
this.errors.add(new CSARErrorContentMismatch());
}
@@ -196,7 +204,8 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
}
- private void validateSources(Path csarRootDirectory, CSARArchive.Manifest manifest) throws NoSuchAlgorithmException, IOException {
+ private void validateSources(Path csarRootDirectory, CSARArchive.Manifest manifest)
+ throws NoSuchAlgorithmException, IOException {
final List<SourcesParser.Source> sources = manifest.getSources();
for (SourcesParser.Source source : sources) {
if (!source.getAlgorithm().isEmpty() || !source.getHash().isEmpty()) {
@@ -205,7 +214,8 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
}
- private void validateSource(Path csarRootDirectory, SourcesParser.Source source) throws NoSuchAlgorithmException, IOException {
+ private void validateSource(Path csarRootDirectory, SourcesParser.Source source)
+ throws NoSuchAlgorithmException, IOException {
final Path sourcePath = csarRootDirectory.resolve(source.getValue());
if (!sourcePath.toFile().exists()) {
this.errors.add(new CSARErrorUnableToFindSource(source.getValue()));
@@ -218,14 +228,16 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
}
- private void validateSourceHashCode(Path csarRootDirectory, SourcesParser.Source source) throws NoSuchAlgorithmException, IOException {
+ private void validateSourceHashCode(Path csarRootDirectory, SourcesParser.Source source)
+ throws NoSuchAlgorithmException, IOException {
String hashCode = generateHashCode(csarRootDirectory, source);
if (!hashCode.equals(source.getHash())) {
this.errors.add(new CSARErrorWrongHashCode(source.getValue()));
}
}
- private String generateHashCode(Path csarRootDirectory, SourcesParser.Source source) throws NoSuchAlgorithmException, IOException {
+ private String generateHashCode(Path csarRootDirectory, SourcesParser.Source source)
+ throws NoSuchAlgorithmException, IOException {
final byte[] sourceData = Files.readAllBytes(csarRootDirectory.resolve(source.getValue()));
final String algorithm = source.getAlgorithm();
@@ -244,27 +256,27 @@ public class VTPValidateCSARR130206 extends VTPValidateCSARBase {
}
-}
+ class ManifestFileSignatureValidator {
-class ManifestFileSignatureValidator {
- private static final Logger LOG = LoggerFactory.getLogger(ManifestFileSignatureValidator.class);
- private final ManifestFileSplitter manifestFileSplitter = new ManifestFileSplitter();
- private final CmsSignatureValidator cmsSignatureValidator = new CmsSignatureValidator();
+ private final Logger LOG = LoggerFactory.getLogger(ManifestFileSignatureValidator.class);
+ private final ManifestFileSplitter manifestFileSplitter = new ManifestFileSplitter();
+ private final CmsSignatureValidator cmsSignatureValidator = new CmsSignatureValidator();
- boolean isValid(File manifestFile) {
- try {
- ManifestFileModel mf = manifestFileSplitter.split(manifestFile);
- return cmsSignatureValidator.verifySignedData(toBytes(mf.getCMS(), mf.getNewLine()),
- Optional.empty(),
- toBytes(mf.getData(), mf.getNewLine()));
- } catch (CmsSignatureValidatorException e) {
- LOG.error("Unable to verify signed data!", e);
- return false;
+ boolean isValid(File manifestFile) {
+ try {
+ ManifestFileModel mf = manifestFileSplitter.split(manifestFile);
+ return cmsSignatureValidator.verifySignedData(toBytes(mf.getCMS(), mf.getNewLine()),
+ Optional.empty(),
+ toBytes(mf.getData(), mf.getNewLine()));
+ } catch (CmsSignatureValidatorException e) {
+ LOG.error("Unable to verify signed data!", e);
+ return false;
+ }
}
- }
- private byte[] toBytes(List<String> data, String newLine) {
- final String updatedData = data.stream().map(it -> it + newLine).collect(Collectors.joining());
- return updatedData.getBytes(Charset.defaultCharset());
+ private byte[] toBytes(List<String> data, String newLine) {
+ final String updatedData = data.stream().map(it -> it + newLine).collect(Collectors.joining());
+ return updatedData.getBytes(Charset.defaultCharset());
+ }
}
}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR146092.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR146092.java
index c9a4de1..fd6a32f 100644
--- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR146092.java
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR146092.java
@@ -17,20 +17,20 @@
package org.onap.cvc.csar.cc.sol004;
-
-import org.onap.cli.fw.schema.OnapCommandSchema;
-import org.onap.cvc.csar.CSARArchive;
-import org.onap.cvc.csar.PnfCSARError;
-import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorEntryMissing;
-import org.onap.cvc.csar.cc.VTPValidateCSARBase;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import org.onap.cli.fw.schema.OnapCommandSchema;
+import org.onap.cvc.csar.CSARArchive;
+import org.onap.cvc.csar.CSARArchive.CSARError;
+import org.onap.cvc.csar.PnfCSARError;
+import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorEntryMissing;
+import org.onap.cvc.csar.cc.VTPValidateCSARBase;
@OnapCommandSchema(schema = "vtp-validate-csar-r146092.yaml")
public class VTPValidateCSARR146092 extends VTPValidateCSARBase {
@@ -38,116 +38,122 @@ public class VTPValidateCSARR146092 extends VTPValidateCSARBase {
private static final int UNKNOWN_LINE_NUMBER = -1;
private static final String SOURCE_ELEMENT_TAG = "Source";
- private static class MissingSourceElementUnderAttributeError extends PnfCSARError {
- private MissingSourceElementUnderAttributeError(String attributeName, String fileName) {
- super("0x2002",
- String.format("Missing. Entry [%s under %s]", SOURCE_ELEMENT_TAG, attributeName),
- UNKNOWN_LINE_NUMBER,
- fileName);
+ @Override
+ protected void validateCSAR(final CSARArchive csar) {
+ if (csar.getManifest().isNonManoAvailable()) {
+ final Optional<ValidateNonManoSection> validateNonManoSection = ValidateNonManoSection.getInstance(csar);
+ if (validateNonManoSection.isPresent()) {
+ errors.addAll(validateNonManoSection.get().validate());
+ }
}
}
- private static class InvalidPathToFileError extends PnfCSARError {
- private InvalidPathToFileError(String attributeName, String pathToSourceFile, String fileName) {
+ @Override
+ protected String getVnfReqsNo() {
+ return "R146092";
+ }
+
+ private static class MissingSourceElementUnderAttributeError extends PnfCSARError {
+
+ private MissingSourceElementUnderAttributeError(final String attributeName, final String fileName) {
super("0x2002",
- String.format("Invalid. Entry [%s under %s has invalid '%s' path]", SOURCE_ELEMENT_TAG, attributeName, pathToSourceFile),
- UNKNOWN_LINE_NUMBER,
- fileName);
+ String.format("Missing. Entry [%s under %s]", SOURCE_ELEMENT_TAG, attributeName),
+ UNKNOWN_LINE_NUMBER,
+ fileName);
}
}
- @Override
- protected void validateCSAR(CSARArchive csar) {
- if(csar.getManifest().isNonManoAvailable()) {
- Optional<ValidateNonManoSection> validateNonManoSection = ValidateNonManoSection.getInstance(csar);
- if(validateNonManoSection.isPresent()) {
- List<CSARArchive.CSARError> csarErrors = validateNonManoSection.get().validate();
- this.errors.addAll(csarErrors);
- }
+ private static class InvalidPathToFileError extends PnfCSARError {
+
+ private InvalidPathToFileError(final String attributeName, final String pathToSourceFile, final String fileName) {
+ super("0x2002",
+ String.format("Invalid. Entry [%s under %s has invalid '%s' path]", SOURCE_ELEMENT_TAG, attributeName,
+ pathToSourceFile),
+ UNKNOWN_LINE_NUMBER,
+ fileName);
}
}
-
private static class ValidateNonManoSection {
+
private final CSARArchive csar;
private final String fileName;
private final Map<String, Map<String, List<String>>> nonMano;
- private final List<CSARArchive.CSARError> errors = new ArrayList<>();
-
- private ValidateNonManoSection(CSARArchive csar, String fileName, Map<String, Map<String, List<String>>> nonMano) {
+ private final List<CSARError> errors = new ArrayList<>();
+ private final List<String> attributeNames = Arrays.asList(
+ "onap_ansible_playbooks",
+ "onap_others",
+ "onap_pm_dictionary",
+ "onap_pnf_sw_information",
+ "onap_scripts",
+ "onap_ves_events",
+ "onap_yang_modules"
+ );
+
+ private ValidateNonManoSection(final CSARArchive csar, final String fileName,
+ final Map<String, Map<String, List<String>>> nonMano) {
this.csar = csar;
this.fileName = fileName;
this.nonMano = nonMano;
}
- static Optional<ValidateNonManoSection> getInstance(CSARArchive csar) {
+ static Optional<ValidateNonManoSection> getInstance(final CSARArchive csar) {
final File manifestMfFile = csar.getManifestMfFile();
- if(manifestMfFile == null){
+ if (manifestMfFile == null) {
return Optional.empty();
}
final String fileName = manifestMfFile.getName();
final Map<String, Map<String, List<String>>> nonMano = csar.getManifest().getNonMano();
- return Optional.of(new ValidateNonManoSection(csar, fileName,nonMano));
+ return Optional.of(new ValidateNonManoSection(csar, fileName, nonMano));
}
- public List<CSARArchive.CSARError> validate() {
-
- List<String> attributeNames = Arrays.asList(
- "onap_ves_events",
- "onap_pm_dictionary",
- "onap_yang_modules",
- "onap_others"
- );
-
- for (String attributeName : attributeNames) {
- validateAttribute(attributeName);
+ public List<CSARError> validate() {
+ if (nonMano.keySet().stream().filter(Objects::nonNull).count() > 0) {
+ nonMano.keySet().stream().filter(Objects::nonNull).forEach(this::validateAttribute);
+ } else {
+ errors.add(new PnfCSARErrorEntryMissing(
+ attributeNames.toString(),
+ fileName,
+ UNKNOWN_LINE_NUMBER)
+ );
}
- return this.errors;
+ return errors;
}
- private void validateAttribute(String attributeName) {
- Set<String> nonManoAttributes = this.nonMano.keySet();
- if (!nonManoAttributes.contains(attributeName)) {
- this.errors.add(new PnfCSARErrorEntryMissing(
- attributeName,
- this.fileName,
- UNKNOWN_LINE_NUMBER)
+ private void validateAttribute(final String nonManoAttributes) {
+
+ if (!attributeNames.contains(nonManoAttributes)) {
+ errors.add(new PnfCSARErrorEntryMissing(
+ nonManoAttributes,
+ fileName,
+ UNKNOWN_LINE_NUMBER)
);
} else {
- validateSourceElementsUnderAttribute(attributeName);
+ validateSourceElementsUnderAttribute(nonManoAttributes);
}
}
- private void validateSourceElementsUnderAttribute(String attributeName) {
+ private void validateSourceElementsUnderAttribute(final String attributeName) {
- Map<String, List<String>> attributeElements = this.nonMano.get(attributeName);
- Set<String> attributeElementNames = attributeElements.keySet();
+ final Map<String, List<String>> attributeElements = nonMano.get(attributeName);
+ final Set<String> attributeElementNames = attributeElements.keySet();
if (!attributeElementNames.contains(SOURCE_ELEMENT_TAG)) {
- this.errors.add(new MissingSourceElementUnderAttributeError(attributeName, this.fileName));
+ errors.add(new MissingSourceElementUnderAttributeError(attributeName, fileName));
} else {
validateThatSourceFileExists(attributeName, attributeElements);
}
}
- private void validateThatSourceFileExists(String attributeName, Map<String, List<String>> attributeElements) {
- for (String pathToFile : attributeElements.get(SOURCE_ELEMENT_TAG)) {
- File fileFromCsar = this.csar.getFileFromCsar(pathToFile);
+ private void validateThatSourceFileExists(final String attributeName, final Map<String, List<String>> attributeElements) {
+ attributeElements.get(SOURCE_ELEMENT_TAG).forEach(pathToFile -> {
+ final File fileFromCsar = csar.getFileFromCsar(pathToFile);
if (!fileFromCsar.exists()) {
- this.errors.add(
- new InvalidPathToFileError(attributeName,
- pathToFile, this.fileName)
- );
+ errors.add(new InvalidPathToFileError(attributeName, pathToFile, fileName));
}
- }
+ });
}
}
- @Override
- protected String getVnfReqsNo() {
- return "R146092";
- }
-
-
}
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR972082.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR972082.java
new file mode 100644
index 0000000..1061480
--- /dev/null
+++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR972082.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2019 Nordix
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.onap.cvc.csar.cc.sol004;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.cli.fw.schema.OnapCommandSchema;
+import org.onap.cvc.csar.CSARArchive;
+import org.onap.cvc.csar.CSARArchive.CSARError;
+import org.onap.cvc.csar.PnfCSARError;
+import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorEntryMissing;
+import org.onap.cvc.csar.cc.VTPValidateCSARBase;
+import org.onap.cvc.csar.cc.sol004.VTPValidateCSARR972082.PnfSoftwareInformation.PnfSoftwareInformationField;
+import org.onap.cvc.csar.cc.sol004.VTPValidateCSARR972082.PnfSoftwareInformation.PnfSoftwareVersion;
+import org.onap.cvc.csar.cc.sol004.VTPValidateCSARR972082.PnfSoftwareInformation.PnfSoftwareVersion.PnfSoftwareVersionField;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.error.YAMLException;
+
+@OnapCommandSchema(schema = "vtp-validate-csar-r972082.yaml")
+public class VTPValidateCSARR972082 extends VTPValidateCSARBase {
+
+ private static final int UNKNOWN_LINE_NUMBER = -1;
+ private static final String SOURCE_ELEMENT_TAG = "Source";
+ private static final String ERROR_CODE = "0x2002";
+
+ @Override
+ protected void validateCSAR(final CSARArchive csar) {
+ if (csar.getManifest().isNonManoAvailable()) {
+ final Optional<ValidateNonManoSection> validateNonManoSection = ValidateNonManoSection.getInstance(csar);
+ if (validateNonManoSection.isPresent()) {
+ final List<CSARError> csarErrors = validateNonManoSection.get().validate();
+ errors.addAll(csarErrors);
+ }
+ }
+ }
+
+ @Override
+ protected String getVnfReqsNo() {
+ return "R972082";
+ }
+
+ private static class MissingSourceElementUnderAttributeError extends PnfCSARError {
+
+ private MissingSourceElementUnderAttributeError(final String attributeName, final String fileName) {
+ super(ERROR_CODE,
+ String.format("Missing. Entry [%s under %s]", SOURCE_ELEMENT_TAG, attributeName),
+ UNKNOWN_LINE_NUMBER,
+ fileName);
+ }
+ }
+
+ private static class MissingSoftwareInformationError extends PnfCSARError {
+
+ private MissingSoftwareInformationError(final String fileName) {
+ super(ERROR_CODE,
+ String.format("Missing. Entry [%s in %s]", "pnf_software_version", fileName),
+ UNKNOWN_LINE_NUMBER,
+ fileName);
+ }
+ }
+
+ private static class InvalidPathToFileError extends PnfCSARError {
+
+ private InvalidPathToFileError(final String attributeName, final String pathToSourceFile, final String fileName) {
+ super(ERROR_CODE,
+ String.format("Invalid. Entry [%s under %s has invalid '%s' path]", SOURCE_ELEMENT_TAG, attributeName,
+ pathToSourceFile),
+ UNKNOWN_LINE_NUMBER,
+ fileName);
+ }
+ }
+
+ private static class InvalidYamlStructureError extends PnfCSARError {
+
+ private InvalidYamlStructureError(final String fileName) {
+ super(ERROR_CODE,
+ String.format("Invalid. Yaml file %s is invalid", fileName),
+ UNKNOWN_LINE_NUMBER,
+ fileName);
+ }
+ }
+
+ private static class ValidateNonManoSection {
+
+ private final CSARArchive csar;
+ private final String fileName;
+ private final Map<String, Map<String, List<String>>> nonMano;
+ private final List<CSARError> errors = new ArrayList<>();
+ private final List<String> attributeNames = Arrays.asList(
+ "onap_pnf_sw_information"
+ );
+
+ private ValidateNonManoSection(final CSARArchive csar, final String fileName,
+ final Map<String, Map<String, List<String>>> nonMano) {
+ this.csar = csar;
+ this.fileName = fileName;
+ this.nonMano = nonMano;
+ }
+
+ static Optional<ValidateNonManoSection> getInstance(final CSARArchive csar) {
+ final File manifestMfFile = csar.getManifestMfFile();
+ if (manifestMfFile == null) {
+ return Optional.empty();
+ }
+ final String fileName = manifestMfFile.getName();
+ final Map<String, Map<String, List<String>>> nonMano = csar.getManifest().getNonMano();
+ return Optional.of(new ValidateNonManoSection(csar, fileName, nonMano));
+ }
+
+ private List<CSARError> validate() {
+ if (nonMano.keySet().stream().filter(Objects::nonNull).count() > 0) {
+ nonMano.keySet().stream().filter(Objects::nonNull).forEach(this::validateAttribute);
+ } else {
+ errors.add(new PnfCSARErrorEntryMissing(
+ attributeNames.toString(),
+ fileName,
+ UNKNOWN_LINE_NUMBER)
+ );
+ }
+
+ return errors;
+ }
+
+ private void validateAttribute(final String nonManoAttributes) {
+
+ if (!attributeNames.contains(nonManoAttributes)) {
+ errors.add(new PnfCSARErrorEntryMissing(
+ nonManoAttributes,
+ fileName,
+ UNKNOWN_LINE_NUMBER)
+ );
+ } else {
+ validateSourceElementsUnderAttribute(nonManoAttributes);
+ }
+ }
+
+ private void validateSourceElementsUnderAttribute(final String attributeName) {
+
+ final Map<String, List<String>> attributeElements = nonMano.get(attributeName);
+ final Set<String> attributeElementNames = attributeElements.keySet();
+
+ if (!attributeElementNames.contains(SOURCE_ELEMENT_TAG)) {
+ errors.add(new MissingSourceElementUnderAttributeError(attributeName, fileName));
+ } else {
+ validateThatSourceFileExists(attributeName, attributeElements);
+ }
+ }
+
+ private void validateThatSourceFileExists(final String attributeName, final Map<String, List<String>> attributeElements) {
+ attributeElements.get(SOURCE_ELEMENT_TAG).forEach(pathToFile -> {
+ final File fileFromCsar = csar.getFileFromCsar(pathToFile);
+ if (!fileFromCsar.exists()) {
+ errors.add(new InvalidPathToFileError(attributeName, pathToFile, fileName));
+ } else {
+ validateSoftwareInformationNonManoArtifact(pathToFile);
+ }
+ });
+ }
+
+ private void validateSoftwareInformationNonManoArtifact(final String swInformationFilePath) {
+ if (StringUtils.isEmpty(swInformationFilePath)) {
+ errors.add(new MissingSourceElementUnderAttributeError("", swInformationFilePath));
+ return;
+ }
+ final Optional<PnfSoftwareInformation> parsedYaml = parse(swInformationFilePath);
+ if (!parsedYaml.isPresent()) {
+ errors.add(new InvalidYamlStructureError(swInformationFilePath));
+ } else {
+ final PnfSoftwareInformation pnfSoftwareInformation = parsedYaml.get();
+ if (!pnfSoftwareInformation.isValid()) {
+ errors.add(new MissingSoftwareInformationError(swInformationFilePath));
+ }
+ }
+ }
+
+ private Object read(final InputStream yamlFileInputStream) {
+ final Yaml yaml = new Yaml();
+ return yaml.load(yamlFileInputStream);
+ }
+
+ private Optional<PnfSoftwareInformation> parse(final String swInformationFilePath) {
+
+ final Map<String, Object> softwareVersionYamlObject;
+ try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
+ Files.readAllBytes(csar.getFileFromCsar(swInformationFilePath).toPath()))) {
+ final Object yaml = read(byteArrayInputStream);
+ if (!(yaml instanceof Map)) {
+ return Optional.empty();
+ }
+
+ softwareVersionYamlObject = (Map<String, Object>) yaml; // unchecked warning suppressed
+ } catch (final IOException | YAMLException e) {
+ return Optional.empty();
+ }
+
+ final PnfSoftwareInformation pnfSoftwareInformation = new PnfSoftwareInformation();
+ pnfSoftwareInformation.setDescription(
+ (String) softwareVersionYamlObject.get(PnfSoftwareInformationField.DESCRIPTION.getFieldName()));
+ pnfSoftwareInformation.setProvider(
+ (String) softwareVersionYamlObject.get(PnfSoftwareInformationField.PROVIDER.getFieldName()));
+ pnfSoftwareInformation.setVersion(
+ (String) softwareVersionYamlObject.get(PnfSoftwareInformationField.VERSION.getFieldName()));
+ final List<Map<String, String>> pnfSoftwareInformationYaml = (List<Map<String, String>>) softwareVersionYamlObject
+ .get(PnfSoftwareInformationField.PNF_SOFTWARE_INFORMATION
+ .getFieldName()); // unchecked warning suppressed
+
+ if (CollectionUtils.isNotEmpty(pnfSoftwareInformationYaml)) {
+ pnfSoftwareInformationYaml.forEach(stringStringMap -> {
+ final String description = stringStringMap.get(PnfSoftwareVersionField.DESCRIPTION.getFieldName());
+ final String version = stringStringMap
+ .get(PnfSoftwareVersionField.PNF_SOFTWARE_VERSION.getFieldName());
+ pnfSoftwareInformation.addToSoftwareVersionSet(new PnfSoftwareVersion(version, description));
+ });
+ }
+
+ return Optional.of(pnfSoftwareInformation);
+ }
+ }
+
+ @Getter
+ @Setter
+ static class PnfSoftwareInformation {
+
+ private String description;
+ private String provider;
+ private String version;
+ @Setter(AccessLevel.NONE)
+ private Set<PnfSoftwareVersion> softwareVersionSet = new LinkedHashSet<>();
+
+ /**
+ * Adds a {@link PnfSoftwareVersion} instance to the software version set
+ *
+ * @param softwareVersion the pnf software version to add
+ */
+ private void addToSoftwareVersionSet(final PnfSoftwareVersion softwareVersion) {
+ softwareVersionSet.add(softwareVersion);
+ }
+
+ /**
+ * Stores the software information yaml field names.
+ */
+ @AllArgsConstructor
+ @Getter
+ enum PnfSoftwareInformationField {
+ DESCRIPTION("description"),
+ PROVIDER("provider"),
+ VERSION("version"),
+ PNF_SOFTWARE_INFORMATION("pnf_software_information");
+
+ private final String fieldName;
+
+ }
+
+ private boolean isValid() {
+ if (CollectionUtils.isEmpty(softwareVersionSet)) {
+ return false;
+ }
+
+ return softwareVersionSet.stream().allMatch(PnfSoftwareVersion::isValid);
+ }
+
+ @AllArgsConstructor
+ @EqualsAndHashCode
+ @Getter
+ static class PnfSoftwareVersion {
+
+ private final String version;
+ private final String description;
+
+ /**
+ * Stores the pnf software version yaml fields.
+ */
+ @Getter
+ @AllArgsConstructor
+ enum PnfSoftwareVersionField {
+ DESCRIPTION("description"),
+ PNF_SOFTWARE_VERSION("pnf_software_version");
+
+ private final String fieldName;
+ }
+
+ private boolean isValid() {
+ return StringUtils.isNotEmpty(version);
+ }
+ }
+ }
+}