diff options
Diffstat (limited to 'csarvalidation/src/main/java')
7 files changed, 323 insertions, 41 deletions
diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java b/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java index 9d80605..bc12e55 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/CSARArchive.java @@ -808,7 +808,7 @@ public class CSARArchive implements AutoCloseable { private Definition definition = new Definition(); - private Manifest manifest = new Manifest(); + private Manifest manifest; private File toscaMetaFile; @@ -870,6 +870,14 @@ public class CSARArchive implements AutoCloseable { return errors; } + public CSARArchive(){ + this(new Manifest()); + } + + public CSARArchive(Manifest manifest) { + this.manifest = manifest; + } + private void unzip(String csarPath, Path destination) throws IOException { File csarFile = new File(csarPath); diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java index 9dc966b..b51faf8 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfCSARArchive.java @@ -1,12 +1,12 @@ /** * Copyright 2019 Nokia - * + * <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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * <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. @@ -18,11 +18,17 @@ package org.onap.cvc.csar; import org.apache.commons.lang3.tuple.Pair; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; public class PnfCSARArchive extends CSARArchive { + public PnfCSARArchive(){ + super(new PnfManifest()); + } + @Override void parseManifest() throws IOException { @@ -32,26 +38,41 @@ public class PnfCSARArchive extends CSARArchive { } PnfManifestParser pnfManifestParser = PnfManifestParser.getInstance( - this.getManifestMfFile().getAbsolutePath() + this.getManifestMfFile() ); Pair<Manifest.Metadata, List<CSARError>> metadataData = pnfManifestParser.fetchMetadata(); + Pair<List<String>, List<CSARError>> sourcesSectionData = pnfManifestParser.fetchSourcesSection(); Pair<Map<String, Map<String, List<String>>>, List<CSARError>> nonManoArtifactsData = pnfManifestParser.fetchNonManoArtifacts(); - Manifest manifest = this.getManifest(); + PnfManifest manifest = (PnfManifest) this.getManifest(); manifest.setMetadata(metadataData.getKey()); + manifest.setSources(sourcesSectionData.getKey()); manifest.setNonMano(nonManoArtifactsData.getKey()); this.getErrors().addAll(metadataData.getValue()); this.getErrors().addAll(nonManoArtifactsData.getValue()); + this.getErrors().addAll(sourcesSectionData.getValue()); } @Override - String getEntryManifestParamName(){ + String getEntryManifestParamName() { return "ETSI-Entry-Manifest"; } @Override - String getEntryChangeLogParamName(){ + String getEntryChangeLogParamName() { return "ETSI-Entry-Change-Log"; } + + public static class PnfManifest extends Manifest { + private List<String> sources = new ArrayList<>(); + + public List<String> getSources() { + return Collections.unmodifiableList(sources); + } + + public void setSources(List<String> sources) { + this.sources.addAll(sources); + } + } } diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java index ea52841..5ef74fd 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/PnfManifestParser.java @@ -21,6 +21,7 @@ import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorEntryMissing; import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorInvalidEntry; import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorWarning; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; @@ -34,8 +35,9 @@ import java.util.stream.Stream; class PnfManifestParser { - private static final String METADATA_SECTION = "metadata"; - private static final String NON_MANO_ARTIFACT_SETS_SECTION = "non_mano_artifact_sets"; + private static final String METADATA_SECTION_TAG_SECTION = "metadata"; + private static final String SOURCE_TAG_SECTION = "source"; + private static final String NON_MANO_ARTIFACT_SETS_TAG_SECTION = "non_mano_artifact_sets"; private static final String PRODUCT_NAME = "pnfd_name"; private static final String PROVIDER_ID = "pnfd_provider"; private static final String VERSION = "pnfd_archive_version"; @@ -49,13 +51,14 @@ class PnfManifestParser { this.fileName = fileName; } - static PnfManifestParser getInstance(String fileName) throws IOException { + static PnfManifestParser getInstance(File pnfManifestFile) throws IOException { + String fileName = pnfManifestFile.getAbsolutePath(); try (Stream<String> stream = Files.lines(Paths.get(fileName))) { List<String> lines = stream .map(String::trim) .collect(Collectors.toList()); - return new PnfManifestParser(lines, fileName); + return new PnfManifestParser(lines, pnfManifestFile.getName()); } } @@ -64,20 +67,16 @@ class PnfManifestParser { List<CSARArchive.CSARError> errors = new ArrayList<>(); boolean isMetadataSectionAvailable = false; - int lineNumber = 0; - for (String line : lines) { - lineNumber++; - if (line.trim().isEmpty() || line.trim().startsWith("#")){ - continue; - } else if (line.startsWith(METADATA_SECTION)) { + + for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + String line = lines.get(lineNumber); + Pair<String, String> data = parseLine(line); + + if(data.getKey().toLowerCase().equals(METADATA_SECTION_TAG_SECTION)) { isMetadataSectionAvailable = true; - }else if (isMetadataSectionAvailable) { - Pair<String, String> data = parseLine(line); + }else if (isMetadataSectionAvailable && !isLineExcluded(line)) { - if (isNewSection(data)) { - if(!isSectionSupported(data.getKey())) { - errors.add(new PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); - } + if (shouldStopProcessing(data, errors, lineNumber)) { break; } @@ -86,13 +85,39 @@ class PnfManifestParser { } if (!isMetadataSectionAvailable) { - errors.add(new PnfCSARErrorEntryMissing(METADATA_SECTION, this.fileName, -1)); + errors.add(new PnfCSARErrorEntryMissing(METADATA_SECTION_TAG_SECTION, this.fileName, -1)); } return Pair.of(metadata, errors); } + Pair<List<String>, List<CSARArchive.CSARError>> fetchSourcesSection() { + List<String> sources = new ArrayList<>(); + List<CSARArchive.CSARError> errors = new ArrayList<>(); + boolean isSpecialTagReached = false; + boolean sourceSectionParsing = false; + for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + String line = lines.get(lineNumber); + if (sourceSectionParsing && (startsWith(line, METADATA_SECTION_TAG_SECTION) || startsWith(line, NON_MANO_ARTIFACT_SETS_TAG_SECTION))) { + isSpecialTagReached = true; + }else if (!isSpecialTagReached && startsWith(line, SOURCE_TAG_SECTION)) { + sourceSectionParsing = true; + Pair<String, String> data = parseLine(line); + + String value = data.getValue(); + if (value.isEmpty()) { + errors.add(new PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); + break; + } else { + sources.add(value); + } + } + } + + return Pair.of(sources, errors); + } + Pair<Map<String, Map<String, List<String>>>, List<CSARArchive.CSARError>> fetchNonManoArtifacts() { Map<String, Map<String, List<String>>> nonManoArtifacts = new HashMap<>(); List<CSARArchive.CSARError> errors = new ArrayList<>(); @@ -102,15 +127,14 @@ class PnfManifestParser { for (String line : lines) { - if (line.trim().isEmpty() || line.trim().startsWith("#")) { - continue; - } else if (line.startsWith(NON_MANO_ARTIFACT_SETS_SECTION)) { + if (startsWith(line, NON_MANO_ARTIFACT_SETS_TAG_SECTION)) { isNonManoArtifactsSectionAvailable = true; } else if (isNonManoArtifactsSectionAvailable) { Pair<String, String> data = parseLine(line); if (isNewSection(data)) { attributeName = data.getKey(); + nonManoArtifacts.put(attributeName, new HashMap<>()); continue; } @@ -119,12 +143,32 @@ class PnfManifestParser { } if (!isNonManoArtifactsSectionAvailable) { - errors.add(new PnfCSARErrorEntryMissing(NON_MANO_ARTIFACT_SETS_SECTION, this.fileName, -1)); + errors.add(new PnfCSARErrorEntryMissing(NON_MANO_ARTIFACT_SETS_TAG_SECTION, this.fileName, -1)); } return Pair.of(nonManoArtifacts, errors); } + private boolean isLineExcluded(String line) { + return line.trim().isEmpty() + || startsWith(line, "#") + || startsWith(line,SOURCE_TAG_SECTION); + } + + private boolean shouldStopProcessing(Pair<String, String> data, List<CSARArchive.CSARError> errors, int lineNumber) { + if (isNewSection(data) || data.getKey().toLowerCase().equals(SOURCE_TAG_SECTION)) { + if(!isSectionSupported(data.getKey())) { + errors.add(new PnfCSARErrorWarning(data.getKey(), this.fileName, lineNumber)); + } + return true; + } + return false; + } + + private boolean startsWith(String line, String word){ + return line.trim().toLowerCase().startsWith(word); + } + private void handleMetadataLine( CSARArchive.Manifest.Metadata metadata, List<CSARArchive.CSARError> errors, @@ -172,14 +216,17 @@ class PnfManifestParser { } private boolean isSectionSupported(String key) { - return Lists.newArrayList(METADATA_SECTION, NON_MANO_ARTIFACT_SETS_SECTION).contains(key); + return Lists.newArrayList( + METADATA_SECTION_TAG_SECTION, + SOURCE_TAG_SECTION, + NON_MANO_ARTIFACT_SETS_TAG_SECTION).contains(key.toLowerCase()); } private boolean isNewSection(Pair<String, String> data) { String key = data.getKey().trim(); String value = data.getValue().trim(); - return key.matches("[a-zA-z_0-9]+") && (value.isEmpty() || value.startsWith("#")); + return key.matches("[a-zA-z_0-9]+") && (value.isEmpty() || startsWith(value,"#")); } diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidatePnfCSARBase.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidatePnfCSARBase.java index 2effffd..6c7d3a0 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidatePnfCSARBase.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/VTPValidatePnfCSARBase.java @@ -23,6 +23,7 @@ import org.onap.cvc.csar.PnfCSARArchive; import java.util.List; public abstract class VTPValidatePnfCSARBase extends VTPValidateCSARBase { + @Override protected CSARArchive createArchiveInstance(){ return new PnfCSARArchive(); } 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 new file mode 100644 index 0000000..1cdfe7a --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR146092.java @@ -0,0 +1,144 @@ +/* + * Copyright 2019 Nokia + * <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 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.VTPValidatePnfCSARBase; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@OnapCommandSchema(schema = "vtp-validate-csar-r146092.yaml") +public class VTPValidateCSARR146092 extends VTPValidatePnfCSARBase { + + 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); + } + } + + private static class InvalidPathToFileError extends PnfCSARError { + private InvalidPathToFileError(String attributeName, String pathToSourceFile, String fileName) { + super("0x2002", + String.format("Invalid. Entry [%s under %s has invalid '%s' path]", SOURCE_ELEMENT_TAG, attributeName, pathToSourceFile), + UNKNOWN_LINE_NUMBER, + fileName); + } + } + + @Override + protected void validateCSAR(CSARArchive csar) { + ValidateNonManoSection validateNonManoSection = ValidateNonManoSection.getInstance(csar); + List<CSARArchive.CSARError> csarErrors = validateNonManoSection.validate(); + + this.errors.addAll(csarErrors); + } + + + 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<>(); + + static ValidateNonManoSection getInstance(CSARArchive csar) { + final String fileName = csar.getManifestMfFile().getName(); + final Map<String, Map<String, List<String>>> nonMano = csar.getManifest().getNonMano(); + return new ValidateNonManoSection(csar, fileName,nonMano); + } + + private ValidateNonManoSection(CSARArchive csar, String fileName, Map<String, Map<String, List<String>>> nonMano) { + this.csar = csar; + this.fileName = fileName; + this.nonMano = nonMano; + } + + public List<CSARArchive.CSARError> validate() { + + List<String> attributeNames = Arrays.asList( + "onap_ves_events", + "onap_pm_dictionary", + "onap_yang_module", + "onap_others" + ); + + for (String attributeName : attributeNames) { + validateAttribute(attributeName); + } + + return this.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) + ); + } else { + validateSourceElementsUnderAttribute(attributeName); + } + } + + private void validateSourceElementsUnderAttribute(String attributeName) { + + Map<String, List<String>> attributeElements = this.nonMano.get(attributeName); + List<String> attributeElementNames = attributeElements.keySet().stream() + .map(String::toLowerCase) + .collect(Collectors.toList()); + + if (!attributeElementNames.contains(SOURCE_ELEMENT_TAG)) { + this.errors.add(new MissingSourceElementUnderAttributeError(attributeName, this.fileName)); + } else { + for (String pathToFile : attributeElements.get(SOURCE_ELEMENT_TAG)) { + File fileFromCsar = this.csar.getFileFromCsar(pathToFile); + if (!fileFromCsar.exists()) { + this.errors.add( + new InvalidPathToFileError(attributeName, + pathToFile, this.fileName) + ); + } + } + } + } + } + + @Override + protected String getVnfReqsNo() { + return "R146092"; + } + + +} diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR293901.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR293901.java index 09edc34..b114880 100644 --- a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR293901.java +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR293901.java @@ -33,16 +33,16 @@ public class VTPValidateCSARR293901 extends VTPValidatePnfCSARBase { @Override protected void validateCSAR(CSARArchive csar) { final CSARArchive.TOSCAMeta toscaMeta = csar.getToscaMeta(); - if (Objects.isNull(toscaMeta.getEntryManifestMf())) { - this.errors.add(new PnfCSARErrorEntryMissing( - "ETSI-Entry-Manifest", - CSARArchive.TOSCA_Metadata__TOSCA_Meta, - UNKNOWN_LINE_NUMBER) - ); - } - if (Objects.isNull(toscaMeta.getEntryChangeLog())) { + String entryManifestMf = toscaMeta.getEntryManifestMf(); + + validateToscaMetaValue(entryManifestMf, "ETSI-Entry-Manifest"); + validateToscaMetaValue(toscaMeta.getEntryChangeLog(), "ETSI-Entry-Change-Log"); + } + + private void validateToscaMetaValue(String entryManifestMf, String toscaMetaAttributeName) { + if (Objects.isNull(entryManifestMf)) { this.errors.add(new PnfCSARErrorEntryMissing( - "ETSI-Entry-Change-Log", + toscaMetaAttributeName, CSARArchive.TOSCA_Metadata__TOSCA_Meta, UNKNOWN_LINE_NUMBER) ); diff --git a/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR57019.java b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR57019.java new file mode 100644 index 0000000..8f6118b --- /dev/null +++ b/csarvalidation/src/main/java/org/onap/cvc/csar/cc/sol004/VTPValidateCSARR57019.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Nokia + * <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 org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cvc.csar.CSARArchive; +import org.onap.cvc.csar.PnfCSARError.PnfCSARErrorEntryMissing; +import org.onap.cvc.csar.cc.VTPValidatePnfCSARBase; + +import java.util.Objects; + +@OnapCommandSchema(schema = "vtp-validate-csar-r57019.yaml") +public class VTPValidateCSARR57019 extends VTPValidatePnfCSARBase { + + private static final int UNKNOWN_LINE_NUMBER = -1; + + @Override + protected void validateCSAR(CSARArchive csar) { + final CSARArchive.Manifest.Metadata metadata = csar.getManifest().getMetadata(); + final String fileName = csar.getManifestMfFile().getName(); + + validateMetadataValue(fileName, metadata.getProviderId(), "pnfd_provider"); + validateMetadataValue(fileName, metadata.getProductName(), "pnfd_name"); + validateMetadataValue(fileName, metadata.getReleaseDateTime(), "pnfd_release_date_time"); + validateMetadataValue(fileName, metadata.getPackageVersion(), "pnfd_archive_version"); + + } + + private void validateMetadataValue(String fileName, String providerId, String metadataArgumentName) { + if (Objects.isNull(providerId)) { + this.errors.add(new PnfCSARErrorEntryMissing( + metadataArgumentName, + fileName, + UNKNOWN_LINE_NUMBER) + ); + } + } + + @Override + protected String getVnfReqsNo() { + return "R57019"; + } + + +} |