diff options
Diffstat (limited to 'openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main')
4 files changed, 202 insertions, 46 deletions
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/PMDictionaryValidator.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/PMDictionaryValidator.java new file mode 100644 index 0000000000..a91dd9f445 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/PMDictionaryValidator.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Stream; +import org.onap.validation.yaml.YamlContentValidator; +import org.onap.validation.yaml.error.YamlDocumentValidationError; + +public class PMDictionaryValidator { + + public void validate(Stream<byte[]> pmDictionaryFiles, Consumer<String> errorReporter) { + pmDictionaryFiles + .map(this::validate) + .flatMap(Collection::stream) + .forEach(errorReporter); + } + + private List<String> validate(byte[] fileContent) { + List<String> errors = new ArrayList<>(); + try { + List<YamlDocumentValidationError> validationErrors = new YamlContentValidator().validate(fileContent); + validationErrors.stream() + .map(YamlDocumentValidationError::getMessage) + .forEach(errors::add); + } catch (Exception e) { + errors.add(e.getMessage()); + } + return errors; + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java index f41b44fd79..6107383485 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java @@ -16,6 +16,8 @@ * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= + * * Modifications copyright (c) 2020 Nokia + * ================================================================================ */ package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; @@ -53,6 +55,8 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; + +import java.util.stream.Stream; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FilenameUtils; import org.openecomp.core.impl.ToscaDefinitionImportHandler; @@ -74,6 +78,8 @@ import org.openecomp.sdc.tosca.csar.ToscaMetaEntry; import org.openecomp.sdc.tosca.csar.ToscaMetadata; import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.OnboardingPackageContentHandler; import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.exception.MissingCertificateException; +import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils.FileExtractor; +import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils.InternalFilesFilter; import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.exceptions.InvalidManifestMetadataException; import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManager; import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException; @@ -94,6 +100,7 @@ class SOL004MetaDirectoryValidator implements Validator { private OnboardingPackageContentHandler contentHandler; private Set<String> folderList; private ToscaMetadata toscaMetadata; + private final InternalFilesFilter internalFilesFilter = new InternalFilesFilter(); public SOL004MetaDirectoryValidator() { securityManager = SecurityManager.getInstance(); @@ -114,6 +121,7 @@ class SOL004MetaDirectoryValidator implements Validator { if (packageHasCertificate()) { verifySignedFiles(); } + validatePMDictionaryContentsAgainstSchema(); return Collections.unmodifiableMap(getAnyValidationErrors()); } @@ -132,8 +140,8 @@ class SOL004MetaDirectoryValidator implements Validator { private void parseToscaMetadata() { try { toscaMetadata = - OnboardingToscaMetadata - .parseToscaMetadataFile(contentHandler.getFileContentAsStream(TOSCA_META_PATH_FILE_NAME)); + OnboardingToscaMetadata + .parseToscaMetadataFile(contentHandler.getFileContentAsStream(TOSCA_META_PATH_FILE_NAME)); } catch (final IOException e) { reportError(ErrorLevel.ERROR, Messages.METADATA_PARSER_INTERNAL.getErrorMessage()); LOGGER.error(Messages.METADATA_PARSER_INTERNAL.getErrorMessage(), e.getMessage(), e); @@ -153,7 +161,7 @@ class SOL004MetaDirectoryValidator implements Validator { final Map<String, String> signedFileMap = contentHandler.getFileAndSignaturePathMap(SecurityManager.ALLOWED_SIGNATURE_EXTENSIONS); final String packageCertificatePath = getCertificatePath().orElse(null); final byte[] packageCert = contentHandler.getFileContent(packageCertificatePath); - if(packageCert == null) { + if (packageCert == null) { throw new MissingCertificateException("Expected package certificate"); } signedFileMap.entrySet().stream().filter(entry -> entry.getValue() != null).forEach(entry -> { @@ -164,11 +172,11 @@ class SOL004MetaDirectoryValidator implements Validator { try { if (!securityManager.verifySignedData(fileSignatureBytes, packageCert, fileBytes)) { reportError(ErrorLevel.ERROR, - Messages.ARTIFACT_INVALID_SIGNATURE.formatMessage(fileSignaturePath, filePath)); + Messages.ARTIFACT_INVALID_SIGNATURE.formatMessage(fileSignaturePath, filePath)); } } catch (final SecurityManagerException e) { final String errorMessage = Messages.ARTIFACT_SIGNATURE_VALIDATION_ERROR - .formatMessage(fileSignaturePath, filePath, packageCertificatePath, e.getMessage()); + .formatMessage(fileSignaturePath, filePath, packageCertificatePath, e.getMessage()); reportError(ErrorLevel.ERROR, errorMessage); LOGGER.error(errorMessage, e); } @@ -185,7 +193,7 @@ class SOL004MetaDirectoryValidator implements Validator { } if (!mainDefinitionFileName.equals(manifestFileName)) { reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_INVALID_NAME.getErrorMessage(), - manifestFileName, mainDefinitionFileName)); + manifestFileName, mainDefinitionFileName)); } } @@ -200,14 +208,14 @@ class SOL004MetaDirectoryValidator implements Validator { private boolean hasETSIMetadata() { final Map<String, String> entries = toscaMetadata.getMetaEntries(); return hasEntry(entries, TOSCA_META_FILE_VERSION_ENTRY.getName()) - && hasEntry(entries, CSAR_VERSION_ENTRY.getName()) - && hasEntry(entries, CREATED_BY_ENTRY.getName()); + && hasEntry(entries, CSAR_VERSION_ENTRY.getName()) + && hasEntry(entries, CREATED_BY_ENTRY.getName()); } private boolean hasEntry(final Map<String, String> entries, final String mandatoryEntry) { if (!entries.containsKey(mandatoryEntry)) { reportError(ErrorLevel.ERROR, - String.format(Messages.METADATA_MISSING_ENTRY.getErrorMessage(), mandatoryEntry)); + String.format(Messages.METADATA_MISSING_ENTRY.getErrorMessage(), mandatoryEntry)); return false; } return true; @@ -267,7 +275,7 @@ class SOL004MetaDirectoryValidator implements Validator { } else { final String key = (String) entry.getKey(); reportError(ErrorLevel.ERROR, - String.format(Messages.MANIFEST_INVALID_PNF_METADATA.getErrorMessage(), key)); + String.format(Messages.MANIFEST_INVALID_PNF_METADATA.getErrorMessage(), key)); } } @@ -275,9 +283,9 @@ class SOL004MetaDirectoryValidator implements Validator { private void verifyMetadataEntryVersions(final String key, final String version) { if (!(isValidTOSCAVersion(key, version) || isValidCSARVersion(key, version) - || CREATED_BY_ENTRY.getName().equals(key))) { + || CREATED_BY_ENTRY.getName().equals(key))) { errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, - String.format(Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version))); + String.format(Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version))); LOGGER.error("{}: key {} - value {} ", Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version); } } @@ -288,7 +296,7 @@ class SOL004MetaDirectoryValidator implements Validator { private boolean isValidCSARVersion(final String value, final String version) { return CSAR_VERSION_ENTRY.getName().equals(value) && (CSAR_VERSION_1_1.equals(version) - || CSAR_VERSION_1_0.equals(version)); + || CSAR_VERSION_1_0.equals(version)); } private void validateDefinitionFile(final String filePath) { @@ -296,7 +304,7 @@ class SOL004MetaDirectoryValidator implements Validator { if (verifyFileExists(existingFiles, filePath)) { final ToscaDefinitionImportHandler toscaDefinitionImportHandler = - new ToscaDefinitionImportHandler(contentHandler.getFiles(), filePath); + new ToscaDefinitionImportHandler(contentHandler.getFiles(), filePath); final List<ErrorMessage> validationErrorList = toscaDefinitionImportHandler.getErrors(); if (CollectionUtils.isNotEmpty(validationErrorList)) { errorsByFile.addAll(validationErrorList); @@ -335,8 +343,8 @@ class SOL004MetaDirectoryValidator implements Validator { private void verifyManifestMetadata(final Map<String, String> metadata) { if (metadata.size() != MANIFEST_METADATA_LIMIT) { reportError(ErrorLevel.ERROR, - String.format(Messages.MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT.getErrorMessage(), - MANIFEST_METADATA_LIMIT)); + String.format(Messages.MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT.getErrorMessage(), + MANIFEST_METADATA_LIMIT)); } if (isPnfMetadata(metadata)) { handleMetadataEntries(metadata, MANIFEST_PNF_METADATA); @@ -348,9 +356,9 @@ class SOL004MetaDirectoryValidator implements Validator { private boolean isPnfMetadata(final Map<String, String> metadata) { final String firstMetadataDefinition = metadata.keySet().iterator().next(); final String expectedMetadataType = - firstMetadataDefinition.contains(TOSCA_TYPE_PNF) ? TOSCA_TYPE_PNF : TOSCA_TYPE_VNF; + firstMetadataDefinition.contains(TOSCA_TYPE_PNF) ? TOSCA_TYPE_PNF : TOSCA_TYPE_VNF; if (metadata.keySet().stream() - .anyMatch((final String metadataEntry) -> !metadataEntry.contains(expectedMetadataType))) { + .anyMatch((final String metadataEntry) -> !metadataEntry.contains(expectedMetadataType))) { throw new InvalidManifestMetadataException(Messages.MANIFEST_METADATA_INVALID_ENTRY.getErrorMessage()); } @@ -359,10 +367,10 @@ class SOL004MetaDirectoryValidator implements Validator { private void handleMetadataEntries(final Map<String, String> metadata, final Set<String> manifestMetadata) { manifestMetadata.stream() - .filter(requiredEntry -> !metadata.containsKey(requiredEntry)) - .forEach(requiredEntry -> - reportError(ErrorLevel.ERROR, - String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredEntry))); + .filter(requiredEntry -> !metadata.containsKey(requiredEntry)) + .forEach(requiredEntry -> + reportError(ErrorLevel.ERROR, + String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredEntry))); } /** @@ -372,14 +380,14 @@ class SOL004MetaDirectoryValidator implements Validator { */ private void verifyManifestSources(final Manifest onboardingManifest) { final Set<String> packageFiles = contentHandler.getFileList(); - final List<String> sources = filterSources(onboardingManifest.getSources()); + final List<String> sources = internalFilesFilter.filter(onboardingManifest.getSources()); verifyFilesExist(packageFiles, sources, MANIFEST_SOURCE); final Map<String, List<String>> nonManoArtifacts = onboardingManifest.getNonManoSources(); final List<String> nonManoValidFilePaths = new ArrayList<>(); nonManoArtifacts.forEach((nonManoType, files) -> { - final List<String> internalNonManoFileList = filterSources(files); + final List<String> internalNonManoFileList = internalFilesFilter.filter(files); nonManoValidFilePaths.addAll(internalNonManoFileList); final NonManoArtifactType nonManoArtifactType = NonManoArtifactType.parse(nonManoType).orElse(null); if (nonManoArtifactType == ONAP_PM_DICTIONARY || nonManoArtifactType == ONAP_VES_EVENTS) { @@ -404,24 +412,24 @@ class SOL004MetaDirectoryValidator implements Validator { } if (files.size() != 1) { final String formattedFileList = files.stream() - .map(filePath -> String.format("'%s'", filePath)) - .collect(Collectors.joining(", ")); + .map(filePath -> String.format("'%s'", filePath)) + .collect(Collectors.joining(", ")); reportError(ErrorLevel.ERROR, - Messages.UNIQUE_SW_INFORMATION_NON_MANO_ERROR.formatMessage(formattedFileList)); + Messages.UNIQUE_SW_INFORMATION_NON_MANO_ERROR.formatMessage(formattedFileList)); return; } final String swInformationFilePath = files.get(0); final byte[] swInformationYaml = contentHandler.getFileContent(swInformationFilePath); final Optional<PnfSoftwareInformation> parsedYaml = SoftwareInformationArtifactYamlParser - .parse(swInformationYaml); - if(!parsedYaml.isPresent()) { + .parse(swInformationYaml); + if (!parsedYaml.isPresent()) { reportError(ErrorLevel.ERROR, - Messages.INVALID_SW_INFORMATION_NON_MANO_ERROR.formatMessage(swInformationFilePath)); + Messages.INVALID_SW_INFORMATION_NON_MANO_ERROR.formatMessage(swInformationFilePath)); } else { final PnfSoftwareInformation pnfSoftwareInformation = parsedYaml.get(); if (!pnfSoftwareInformation.isValid()) { reportError(ErrorLevel.ERROR, - Messages.INCORRECT_SW_INFORMATION_NON_MANO_ERROR.formatMessage(swInformationFilePath)); + Messages.INCORRECT_SW_INFORMATION_NON_MANO_ERROR.formatMessage(swInformationFilePath)); } } } @@ -469,29 +477,19 @@ class SOL004MetaDirectoryValidator implements Validator { packageFileSet.forEach(filePath -> { if (!isManifestFile(filePath) && !referredFileSet.contains(filePath)) { reportError(ErrorLevel.ERROR, - String.format(Messages.MISSING_MANIFEST_REFERENCE.getErrorMessage(), filePath)); + String.format(Messages.MISSING_MANIFEST_REFERENCE.getErrorMessage(), filePath)); } }); } - + private boolean isManifestFile(final String filePath) { return filePath.equals(toscaMetadata.getMetaEntries().get(ETSI_ENTRY_MANIFEST.getName())); } - private List<String> filterSources(final List<String> source) { - return source.stream() - .filter(this::externalFileReferences) - .collect(Collectors.toList()); - } - - private boolean externalFileReferences(final String filePath) { - return !filePath.contains("://"); - } - private void validateOtherEntries(final String folderPath) { if (!verifyFoldersExist(folderList, folderPath)) { reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_OPTIONAL_FOLDERS.getErrorMessage(), - folderPath)); + folderPath)); } } @@ -499,7 +497,7 @@ class SOL004MetaDirectoryValidator implements Validator { final Set<String> packageFiles = contentHandler.getFileList(); if (!verifyFileExist(packageFiles, file)) { reportError(ErrorLevel.ERROR, - String.format(Messages.MISSING_METADATA_FILES.getErrorMessage(), file, file)); + String.format(Messages.MISSING_METADATA_FILES.getErrorMessage(), file, file)); } } @@ -511,7 +509,7 @@ class SOL004MetaDirectoryValidator implements Validator { sources.forEach(file -> { if (!existingFiles.contains(file)) { reportError(ErrorLevel.ERROR, - String.format(Messages.MISSING_MANIFEST_SOURCE.getErrorMessage(), type, file)); + String.format(Messages.MISSING_MANIFEST_SOURCE.getErrorMessage(), type, file)); } }); } @@ -538,4 +536,15 @@ class SOL004MetaDirectoryValidator implements Validator { errors.put(SdcCommon.UPLOAD_FILE, errorsByFile); return errors; } + + private void validatePMDictionaryContentsAgainstSchema() { + final Stream<byte[]> pmDictionaryFiles = new FileExtractor(getEtsiEntryManifestPath(), contentHandler) + .findFiles(ONAP_PM_DICTIONARY); + new PMDictionaryValidator() + .validate(pmDictionaryFiles, (String message) -> reportError(ErrorLevel.ERROR, message)); + } + + private String getEtsiEntryManifestPath() { + return toscaMetadata.getMetaEntries().get(ETSI_ENTRY_MANIFEST.getName()); + } } diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/utils/FileExtractor.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/utils/FileExtractor.java new file mode 100644 index 0000000000..c6d7d637fa --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/utils/FileExtractor.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; +import org.openecomp.sdc.be.config.NonManoArtifactType; +import org.openecomp.sdc.tosca.csar.Manifest; +import org.openecomp.sdc.tosca.csar.SOL004ManifestOnboarding; +import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.OnboardingPackageContentHandler; + +public class FileExtractor { + + private final InternalFilesFilter internalFilesFilter; + private final String etsiEntryManifestFilePath; + private final OnboardingPackageContentHandler contentHandler; + + public FileExtractor(String etsiEntryManifestPath, OnboardingPackageContentHandler contentHandler) { + this(etsiEntryManifestPath, contentHandler, new InternalFilesFilter()); + } + + FileExtractor(String etsiEntryManifestPath, OnboardingPackageContentHandler contentHandler, InternalFilesFilter internalFilesFilter) { + this.etsiEntryManifestFilePath = etsiEntryManifestPath; + this.contentHandler = contentHandler; + this.internalFilesFilter = internalFilesFilter; + } + + public Stream<byte[]> findFiles(NonManoArtifactType fileType) { + Map<String, List<String>> nonManoSources = extractNonManoSources(); + List<String> pathsToSources = nonManoSources.getOrDefault(fileType.getType(), new ArrayList<>()); + List<String> pathsToLocalFiles = internalFilesFilter.filter(pathsToSources); + return pathsToLocalFiles.stream() + .map(contentHandler::getFileContent); + } + + private Map<String, List<String>> extractNonManoSources() { + Manifest onboardingManifest = new SOL004ManifestOnboarding(); + onboardingManifest.parse(contentHandler.getFileContentAsStream(etsiEntryManifestFilePath)); + return onboardingManifest.getNonManoSources(); + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/utils/InternalFilesFilter.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/utils/InternalFilesFilter.java new file mode 100644 index 0000000000..50dcd0ce29 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/utils/InternalFilesFilter.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils; + +import java.util.List; +import java.util.stream.Collectors; + +public class InternalFilesFilter { + + public List<String> filter(final List<String> sources) { + return sources.stream() + .filter(this::isInternalFile) + .collect(Collectors.toList()); + } + + private boolean isInternalFile(final String filePath) { + return !filePath.contains("://"); + } +} |