diff options
author | bilal.iqbal <bilal.iqbal@est.tech> | 2019-03-10 00:47:55 +0000 |
---|---|---|
committer | bilal.iqbal <bilal.iqbal@est.tech> | 2019-03-10 00:47:55 +0000 |
commit | 0a1d82ac04a8ef78bfdcbcced4f5096c050edcfe (patch) | |
tree | 0d0dcc04d8ef8d77a00df89ddf93e31c5f5c0433 | |
parent | 90c460aa3c23c9a12885894b4664f7c742c8d29f (diff) |
CSAR Package validation
Change-Id: I11af8d93f5a2cd0566a5caf0dad0519d70bd57d7
Issue-ID: SDC-2147
Issue-ID: SDC-2148
Issue-ID: SDC-2149
Issue-ID: SDC-2150
Signed-off-by: bilal.iqbal <bilal.iqbal@est.tech>
39 files changed, 1548 insertions, 145 deletions
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml index bfa026388e..ee498e61a8 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/pom.xml @@ -71,6 +71,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java index a3772d9298..af5512d119 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/OrchestrationTemplateCSARHandler.java @@ -3,6 +3,7 @@ * Copyright (c) 2018 AT&T Intellectual Property. * Modifications Copyright (c) 2018 Verizon Property. + * Modifications 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. @@ -29,48 +30,36 @@ import org.openecomp.sdc.common.utils.CommonUtil; import org.openecomp.sdc.common.utils.SdcCommon; import org.openecomp.sdc.datatypes.error.ErrorLevel; import org.openecomp.sdc.datatypes.error.ErrorMessage; -import org.openecomp.sdc.logging.api.Logger; -import org.openecomp.sdc.logging.api.LoggerFactory; -import org.openecomp.sdc.tosca.csar.ToscaMetadata; import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData; import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails; -import org.openecomp.sdc.tosca.csar.Manifest; -import org.openecomp.sdc.tosca.csar.OnboardingManifest; -import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata; -import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.exceptions.OrchestrationTemplateHandlerException; +import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.Validator; +import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.ValidatorFactory; import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.CandidateService; import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse; import java.io.IOException; -import java.io.InputStream; import java.nio.ByteBuffer; -import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters; -import static org.openecomp.sdc.tosca.csar.CSARConstants.ELIGBLE_FOLDERS; -import static org.openecomp.sdc.tosca.csar.CSARConstants.ELIGIBLE_FILES; -import static org.openecomp.sdc.tosca.csar.CSARConstants.MAIN_SERVICE_TEMPLATE_MF_FILE_NAME; -import static org.openecomp.sdc.tosca.csar.CSARConstants.MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME; -import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; -import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME; public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateHandler implements OrchestrationTemplateFileHandler { - private static Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCSARHandler.class); + @Override public Optional<FileContentHandler> getFileContentMap(UploadFileResponse uploadFileResponse, byte[] uploadedFileData) { FileContentHandler contentMap = null; - List<String> folderList = new ArrayList<>(); + List<String> folderList; try { Pair<FileContentHandler, List<String>> fileContentMapFromOrchestrationCandidateZip = CommonUtil.getFileContentMapFromOrchestrationCandidateZip(uploadedFileData); contentMap = fileContentMapFromOrchestrationCandidateZip.getKey(); folderList = fileContentMapFromOrchestrationCandidateZip.getRight(); + Validator validator = ValidatorFactory.getValidator(contentMap); + uploadFileResponse.addStructureErrors(validator.validateContent(contentMap, folderList)); } catch (IOException exception) { logger.error(exception.getMessage(), exception); uploadFileResponse.addStructureError( @@ -81,113 +70,8 @@ public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateH uploadFileResponse.addStructureError( SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, coreException.getMessage())); } - validateContent(uploadFileResponse, contentMap, folderList); - return Optional.ofNullable(contentMap); - } - - private void validateContent(UploadFileResponse uploadFileResponse, FileContentHandler contentMap, - List<String> folderList) { - validateManifest(uploadFileResponse, contentMap); - validateMetadata(uploadFileResponse, contentMap); - validateNoExtraFiles(uploadFileResponse, contentMap); - validateFolders(uploadFileResponse, folderList); - } - - private void validateMetadata(UploadFileResponse uploadFileResponse, - FileContentHandler contentMap){ - if (!validateTOSCAYamlFileInRootExist(contentMap, MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME)) { - try (InputStream metaFileContent = contentMap.getFileContent(TOSCA_META_PATH_FILE_NAME)) { - - ToscaMetadata onboardingToscaMetadata = OnboardingToscaMetadata.parseToscaMetadataFile(metaFileContent); - String entryDefinitionsPath = onboardingToscaMetadata.getMetaEntries().get(TOSCA_META_ENTRY_DEFINITIONS); - if (entryDefinitionsPath != null) { - validateFileExist(uploadFileResponse, contentMap, entryDefinitionsPath); - } else { - uploadFileResponse.addStructureError( - SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, - Messages.METADATA_NO_ENTRY_DEFINITIONS.getErrorMessage())); - } - } catch (IOException exception) { - logger.error(exception.getMessage(), exception); - uploadFileResponse.addStructureError( - SdcCommon.UPLOAD_FILE, - new ErrorMessage(ErrorLevel.ERROR, Messages.FAILED_TO_VALIDATE_METADATA.getErrorMessage())); - } - } else { - validateFileExist(uploadFileResponse, contentMap, MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME); - } - } - - private void validateManifest(UploadFileResponse uploadFileResponse, - FileContentHandler contentMap) { - - if (!validateFileExist(uploadFileResponse, contentMap, MAIN_SERVICE_TEMPLATE_MF_FILE_NAME)) { - return; - } - - try (InputStream fileContent = contentMap.getFileContent(MAIN_SERVICE_TEMPLATE_MF_FILE_NAME)) { - - Manifest onboardingManifest = OnboardingManifest.parse(fileContent); - if (!onboardingManifest.isValid()) { - onboardingManifest.getErrors().forEach(error -> uploadFileResponse.addStructureError( - SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, error))); - } - - } catch (IOException e) { - // convert to runtime to keep the throws unchanged - throw new OrchestrationTemplateHandlerException("Failed to validate manifest", e); - } - } - - private void validateNoExtraFiles(UploadFileResponse uploadFileResponse, - FileContentHandler contentMap) { - List<String> unwantedFiles = contentMap.getFileList().stream() - .filter(this::filterFiles).collect(Collectors.toList()); - if (!unwantedFiles.isEmpty()) { - unwantedFiles.stream().filter(this::filterFiles).forEach(unwantedFile -> - uploadFileResponse.addStructureError( - SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, - getErrorWithParameters(Messages.CSAR_FILES_NOT_ALLOWED.getErrorMessage(), - unwantedFile)))); - } - } - - private void validateFolders(UploadFileResponse uploadFileResponse, List<String> folderList) { - List<String> filterResult = - folderList.stream().filter(this::filterFolders).collect(Collectors.toList()); - if (!filterResult.isEmpty()) { - folderList.stream().filter(this::filterFolders).forEach(unwantedFolder -> - uploadFileResponse.addStructureError( - SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, - getErrorWithParameters(Messages.CSAR_DIRECTORIES_NOT_ALLOWED.getErrorMessage(), - unwantedFolder)))); - } - } - - private boolean filterFiles(String inFileName) { - boolean valid = ELIGIBLE_FILES.stream().anyMatch(fileName -> fileName.equals(inFileName)); - return !valid && filterFolders(inFileName); - } - - private boolean filterFolders(String fileName) { - return ELIGBLE_FOLDERS.stream().noneMatch(fileName::startsWith); - } - - private boolean validateTOSCAYamlFileInRootExist(FileContentHandler contentMap, String fileName) { - return contentMap.containsFile(fileName); - } - - private boolean validateFileExist(UploadFileResponse uploadFileResponse, - FileContentHandler contentMap, String fileName) { - - boolean containsFile = contentMap.containsFile(fileName); - if (!containsFile) { - uploadFileResponse.addStructureError( - SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, - getErrorWithParameters(Messages.CSAR_FILE_NOT_FOUND.getErrorMessage(), fileName))); - } - return containsFile; + return Optional.ofNullable(contentMap); } @Override @@ -210,7 +94,6 @@ public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateH return false; } - @Override protected OnboardingTypesEnum getHandlerType() { return OnboardingTypesEnum.CSAR; diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidator.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidator.java new file mode 100644 index 0000000000..0f44427edd --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidator.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * Modification 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.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.common.utils.SdcCommon; +import org.openecomp.sdc.datatypes.error.ErrorLevel; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.tosca.csar.Manifest; +import org.openecomp.sdc.tosca.csar.OnboardingManifest; +import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata; +import org.openecomp.sdc.tosca.csar.ToscaMetadata; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters; +import static org.openecomp.sdc.tosca.csar.CSARConstants.ELIGBLE_FOLDERS; +import static org.openecomp.sdc.tosca.csar.CSARConstants.ELIGIBLE_FILES; +import static org.openecomp.sdc.tosca.csar.CSARConstants.MAIN_SERVICE_TEMPLATE_MF_FILE_NAME; +import static org.openecomp.sdc.tosca.csar.CSARConstants.MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME; + +class ONAPCsarValidator implements Validator { + + private static Logger logger = LoggerFactory.getLogger(ONAPCsarValidator.class); + + private List<ErrorMessage> uploadFileErrors = new ArrayList<>(); + + @Override + public Map<String, List<ErrorMessage>> validateContent(FileContentHandler contentHandler, List<String> folderList) { + + Map<String, List<ErrorMessage>> errors = new HashMap<>(); + validateManifest(contentHandler); + validateMetadata(contentHandler); + validateNoExtraFiles(contentHandler); + validateFolders(folderList); + + if(uploadFileErrors == null || uploadFileErrors.isEmpty()){ + return errors; + } + errors.put(SdcCommon.UPLOAD_FILE, uploadFileErrors); + return errors; + } + + private void validateMetadata(FileContentHandler contentMap){ + if (!validateTOSCAYamlFileInRootExist(contentMap, MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME)) { + try (InputStream metaFileContent = contentMap.getFileContent(TOSCA_META_PATH_FILE_NAME)) { + + ToscaMetadata onboardingToscaMetadata = OnboardingToscaMetadata.parseToscaMetadataFile(metaFileContent); + String entryDefinitionsPath = onboardingToscaMetadata.getMetaEntries().get(TOSCA_META_ENTRY_DEFINITIONS); + if (entryDefinitionsPath != null) { + validateFileExist(contentMap, entryDefinitionsPath); + } else { + uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR, + Messages.METADATA_NO_ENTRY_DEFINITIONS.getErrorMessage())); + } + } catch (IOException exception) { + logger.error(exception.getMessage(), exception); + uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR, + Messages.FAILED_TO_VALIDATE_METADATA.getErrorMessage())); + } + } else { + validateFileExist(contentMap, MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME); + } + } + + private void validateManifest(FileContentHandler contentMap) { + + if (!validateFileExist(contentMap, MAIN_SERVICE_TEMPLATE_MF_FILE_NAME)) { + return; + } + + try (InputStream fileContent = contentMap.getFileContent(MAIN_SERVICE_TEMPLATE_MF_FILE_NAME)) { + + Manifest onboardingManifest = OnboardingManifest.parse(fileContent); + if (!onboardingManifest.isValid()) { + onboardingManifest.getErrors().forEach(error -> uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR, + error))); + } + + } catch (IOException e) { + // convert to runtime to keep the throws unchanged + throw new RuntimeException("Failed to validateContent manifest", e); + } + } + + private void validateNoExtraFiles(FileContentHandler contentMap) { + List<String> unwantedFiles = contentMap.getFileList().stream() + .filter(this::filterFiles).collect(Collectors.toList()); + if (!unwantedFiles.isEmpty()) { + unwantedFiles.stream().filter(this::filterFiles).forEach(unwantedFile -> + uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR, + getErrorWithParameters(Messages.CSAR_FILES_NOT_ALLOWED.getErrorMessage(), unwantedFile)))); + } + } + + private void validateFolders(List<String> folderList) { + List<String> filterResult = + folderList.stream().filter(this::filterFolders).collect(Collectors.toList()); + if (!filterResult.isEmpty()) { + folderList.stream().filter(this::filterFolders).forEach(unwantedFolder -> + uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR, + getErrorWithParameters(Messages.CSAR_DIRECTORIES_NOT_ALLOWED.getErrorMessage(), + unwantedFolder)))); + } + } + + private boolean filterFiles(String inFileName) { + boolean valid = ELIGIBLE_FILES.stream().anyMatch(fileName -> fileName.equals(inFileName)); + return !valid && filterFolders(inFileName); + } + + private boolean filterFolders(String fileName) { + return ELIGBLE_FOLDERS.stream().noneMatch(fileName::startsWith); + } + + private boolean validateTOSCAYamlFileInRootExist(FileContentHandler contentMap, String fileName) { + return contentMap.containsFile(fileName); + } + + private boolean validateFileExist(FileContentHandler contentMap, String fileName) { + + boolean containsFile = contentMap.containsFile(fileName); + if (!containsFile) { + uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR, + getErrorWithParameters(Messages.CSAR_FILE_NOT_FOUND.getErrorMessage(), fileName))); + } + return containsFile; + } +} 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 new file mode 100644 index 0000000000..570eee3736 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java @@ -0,0 +1,360 @@ +/*- + * ============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.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.openecomp.core.converter.ServiceTemplateReaderService; +import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.common.utils.SdcCommon; +import org.openecomp.sdc.datatypes.error.ErrorLevel; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdc.tosca.csar.Manifest; +import org.openecomp.sdc.tosca.csar.OnboardingManifest; +import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata; +import org.openecomp.sdc.tosca.csar.ToscaMetadata; +import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.exceptions.InvalidManifestMetadataException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_0; +import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_1; +import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_METADATA_LIMIT; +import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_PNF_METADATA; +import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_VNF_METADATA; +import static org.openecomp.sdc.tosca.csar.CSARConstants.NON_FILE_IMPORT_ATTRIBUTES; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_FILE_VERSION_ENTRY; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_CREATED_BY_ENTRY; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_CSAR_VERSION_ENTRY; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_CHANGE_LOG; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_LICENSES; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_MANIFEST; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_TESTS; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_FILE_VERSION; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME; + +/** + * Validates the contents of the package to ensure it complies with the "CSAR with TOSCA-Metadata directory" structure + * as defined in ETSI GS NFV-SOL 004 v2.5.1. + * + */ + +class SOL004MetaDirectoryValidator implements Validator{ + + private static final Logger LOGGER = LoggerFactory.getLogger(SOL004MetaDirectoryValidator.class); + + private final List<ErrorMessage> errorsByFile = new ArrayList<>(); + private final Set<String> verifiedImports = new HashSet<>(); + + @Override + public Map<String, List<ErrorMessage>> validateContent(FileContentHandler contentHandler, List<String> folderList) { + validateMetaFile(contentHandler, folderList); + return Collections.unmodifiableMap(getAnyValidationErrors()); + } + + private void validateMetaFile(FileContentHandler contentHandler, List<String> folderList) { + try { + ToscaMetadata toscaMetadata = OnboardingToscaMetadata.parseToscaMetadataFile(contentHandler.getFileContent(TOSCA_META_PATH_FILE_NAME)); + if(toscaMetadata.isValid() && hasETSIMetadata(toscaMetadata)) { + verifyManifestNameAndExtension(toscaMetadata); + handleMetadataEntries(contentHandler, folderList, toscaMetadata); + }else { + errorsByFile.addAll(toscaMetadata.getErrors()); + } + }catch (IOException e){ + reportError(ErrorLevel.ERROR, Messages.METADATA_PARSER_INTERNAL.getErrorMessage()); + LOGGER.error(Messages.METADATA_PARSER_INTERNAL.getErrorMessage(), e.getMessage(), e); + } + } + + private void verifyManifestNameAndExtension(ToscaMetadata toscaMetadata) { + Map<String, String> entries = toscaMetadata.getMetaEntries(); + String manifestFileName = getFileName(entries.get(TOSCA_META_ENTRY_MANIFEST)); + String manifestExtension = getFileExtension(entries.get(TOSCA_META_ENTRY_MANIFEST)); + String mainDefinitionFileName= getFileName(entries.get(TOSCA_META_ENTRY_DEFINITIONS)); + if(!("mf").equals(manifestExtension)){ + reportError(ErrorLevel.ERROR, Messages.MANIFEST_INVALID_EXT.getErrorMessage()); + } + if(!mainDefinitionFileName.equals(manifestFileName)){ + reportError(ErrorLevel.ERROR, Messages.MANIFEST_INVALID_NAME.getErrorMessage()); + } + } + + public String getFileExtension(String filePath){ + return filePath.substring(filePath.lastIndexOf(".") + 1); + } + + private String getFileName(String filePath){ + return filePath.substring(filePath.lastIndexOf("/") + 1, filePath.lastIndexOf(".")); + } + + private boolean hasETSIMetadata(ToscaMetadata toscaMetadata){ + Map<String, String> entries = toscaMetadata.getMetaEntries(); + return hasEntry(entries, TOSCA_META_FILE_VERSION_ENTRY) + && hasEntry(entries, TOSCA_META_CSAR_VERSION_ENTRY) + && hasEntry(entries, TOSCA_META_CREATED_BY_ENTRY); + } + + private boolean hasEntry(Map<String, String> entries, String mandatoryEntry) { + if (!entries.containsKey(mandatoryEntry)) { + reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_ENTRY.getErrorMessage(),mandatoryEntry)); + return false; + } + return true; + } + + private void handleMetadataEntries(FileContentHandler contentHandler, List<String> folderList, ToscaMetadata toscaMetadata) { + for(Map.Entry entry: toscaMetadata.getMetaEntries().entrySet()){ + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + switch (key){ + case TOSCA_META_FILE_VERSION_ENTRY: + case TOSCA_META_CSAR_VERSION_ENTRY: + case TOSCA_META_CREATED_BY_ENTRY: + verifyMetadataEntryVersions(key, value); + break; + case TOSCA_META_ENTRY_DEFINITIONS: + validateDefinitionFile(contentHandler, value); + break; + case TOSCA_META_ENTRY_MANIFEST: + validateManifestFile(contentHandler, value); + break; + case TOSCA_META_ENTRY_CHANGE_LOG: + validateChangeLog(contentHandler, value); + break; + case TOSCA_META_ENTRY_TESTS: + case TOSCA_META_ENTRY_LICENSES: + validateOtherEntries(folderList, value); + break; + default: + errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, String.format(Messages.METADATA_UNSUPPORTED_ENTRY.getErrorMessage(), entry))); + LOGGER.warn(Messages.METADATA_UNSUPPORTED_ENTRY.getErrorMessage(), entry); + break; + } + + } + } + + + private void verifyMetadataEntryVersions(String key, String version) { + if(!(isValidTOSCAVersion(key,version) || isValidCSARVersion(key, version) || TOSCA_META_CREATED_BY_ENTRY.equals(key))) { + errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, Messages.ENTITY_NOT_FOUND.getErrorMessage())); + LOGGER.error("{}: key {} - value {} ", Messages.ENTITY_NOT_FOUND.getErrorMessage(), key, version); + } + } + + private boolean isValidTOSCAVersion(String key, String version){ + return TOSCA_META_FILE_VERSION_ENTRY.equals(key) && TOSCA_META_FILE_VERSION.equals(version); + } + + private boolean isValidCSARVersion(String value, String version){ + return "CSAR-Version".equals(value) && (CSAR_VERSION_1_1.equals(version) + || CSAR_VERSION_1_0.equals(version)); + } + + private void validateDefinitionFile(FileContentHandler contentHandler, String filePath) { + Set<String> existingFiles = contentHandler.getFileList(); + + if (verifyFileExists(existingFiles, filePath)) { + byte[] definitionFile = getFileContent(filePath, contentHandler); + handleImports(contentHandler, filePath, existingFiles, definitionFile); + }else{ + reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_DEFINITION_FILE.getErrorMessage(), filePath)); + } + } + + private void handleImports(FileContentHandler contentHandler, String filePath, Set<String> existingFiles, + byte[] definitionFile) { + try { + ServiceTemplateReaderService readerService = new ServiceTemplateReaderServiceImpl(definitionFile); + List<Object> imports = (readerService).getImports(); + for (Object o : imports) { + String rootDir = "/"; + if (filePath.contains("/")) { + rootDir = filePath.substring(0, filePath.lastIndexOf("/")); + } + String verifiedFile = verifyImport(existingFiles, o, rootDir); + if (verifiedFile != null && !verifiedImports.contains(verifiedFile)) { + verifiedImports.add(verifiedFile); + handleImports(contentHandler, verifiedFile, existingFiles, getFileContent(verifiedFile, + contentHandler)); + } + } + } + catch (Exception e){ + reportError(ErrorLevel.ERROR, String.format(Messages.INVALID_YAML_FORMAT.getErrorMessage(), e.getMessage())); + LOGGER.error("{}", Messages.INVALID_YAML_FORMAT_REASON, e.getMessage(), e); + } + } + + private String verifyImport(Set<String> existingFiles, Object o, String parentDir) { + if(o instanceof String){ + String filePath = ((String) o); + if(!filePath.contains("/")){ + filePath = parentDir + "/" + filePath; + } + if(!verifyFileExists(existingFiles, filePath)){ + reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_IMPORT_FILE.getErrorMessage(), (String) o)); + return null; + } + return filePath; + } else if(o instanceof Map){ + Map<String, Object> o1 = (Map)o; + for(Map.Entry<String, Object> entry: o1.entrySet()){ + if(NON_FILE_IMPORT_ATTRIBUTES.stream().noneMatch(attr -> entry.getKey().equals(attr))){ + verifyImport(existingFiles, entry.getValue(), parentDir); + } + } + }else { + reportError(ErrorLevel.ERROR, Messages.INVALID_IMPORT_STATEMENT.getErrorMessage()); + } + return null; + } + + private boolean verifyFileExists(Set<String> existingFiles, String filePath){ + return existingFiles.contains(filePath); + } + + private byte[] getFileContent(String filename, FileContentHandler contentHandler){ + Map<String, byte[]> files = contentHandler.getFiles(); + return files.get(filename); + } + + private void validateManifestFile(FileContentHandler contentHandler, String filePath){ + final Set<String> exitingFiles = contentHandler.getFileList(); + if(verifyFileExists(exitingFiles, filePath)) { + Manifest onboardingManifest = OnboardingManifest.parse(contentHandler.getFileContent(filePath)); + if(onboardingManifest.isValid()){ + try { + verifyManifestMetadata(onboardingManifest.getMetadata()); + }catch (InvalidManifestMetadataException e){ + reportError(ErrorLevel.ERROR, e.getMessage()); + LOGGER.error(e.getMessage(), e); + } + verifySourcesExists(exitingFiles, onboardingManifest); + }else{ + List<String> manifestErrors = onboardingManifest.getErrors(); + for(String error: manifestErrors){ + reportError(ErrorLevel.ERROR, error); + } + } + }else { + reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_NOT_EXIST.getErrorMessage(), filePath)); + } + } + + private void verifyManifestMetadata(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)); + } + if(isPnfMetadata(metadata)){ + handlePnfMetadataEntries(metadata); + }else { + handleVnfMetadataEntries(metadata); + } + } + + private boolean isPnfMetadata(Map<String, String> metadata) { + String metadataType = null; + for(String key: metadata.keySet()) { + if(metadataType == null){ + metadataType = key.contains("pnf") ? "pnf" : "vnf"; + }else if(!key.contains(metadataType)){ + throw new InvalidManifestMetadataException(Messages.MANIFEST_METADATA_INVALID_ENTRY.getErrorMessage()); + } + } + return "pnf".equals(metadataType); + } + + private void handleVnfMetadataEntries(Map<String, String> metadata) { + for (String requiredPnfEntry : MANIFEST_VNF_METADATA) { + if (!metadata.containsKey(requiredPnfEntry)) { + reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredPnfEntry)); + } + } + } + + private void handlePnfMetadataEntries(Map<String, String> metadata) { + for (String requiredPnfEntry : MANIFEST_PNF_METADATA) { + if (!metadata.containsKey(requiredPnfEntry)) { + reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredPnfEntry)); + } + } + } + + private void verifySourcesExists(Set<String> exitingFiles, Manifest onboardingManifest) { + List<String> sources = onboardingManifest.getSources(); + Map<String, List<String>> nonManoArtifacts = onboardingManifest.getNonManoSources(); + verifyFilesExist(exitingFiles, sources); + for (Map.Entry entry : nonManoArtifacts.entrySet()) { + verifyFilesExist(exitingFiles, (List) entry.getValue()); + } + } + + private void validateOtherEntries(List<String> folderList, String folderPath){ + if(!verifyFoldersExist(folderList, folderPath)) + reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_OPTIONAL_FOLDERS.getErrorMessage(), + folderPath)); + } + + private boolean verifyFoldersExist(List<String> folderList, String folderPath){ + return folderList.contains(folderPath + "/"); + } + + private void verifyFilesExist(Set<String> existingFiles, List<String> sources){ + for(String file: sources){ + if(!verifyFileExists(existingFiles, file)){ + reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_ARTIFACT.getErrorMessage(), file)); + } + + } + } + + private void validateChangeLog(FileContentHandler contentHandler, String filePath){ + if(!verifyFileExists(contentHandler.getFileList(), filePath)){ + reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_ARTIFACT.getErrorMessage(), filePath)); + } + } + + private void reportError(ErrorLevel errorLevel, String errorMessage){ + errorsByFile.add(new ErrorMessage(errorLevel, errorMessage)); + } + + private Map<String, List<ErrorMessage>> getAnyValidationErrors(){ + + if(errorsByFile.isEmpty()){ + return Collections.emptyMap(); + } + Map<String, List<ErrorMessage>> errors = new HashMap<>(); + errors.put(SdcCommon.UPLOAD_FILE, errorsByFile); + 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/Validator.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/Validator.java new file mode 100644 index 0000000000..927f3c0b69 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/Validator.java @@ -0,0 +1,41 @@ +/*- + * ============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.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import java.util.List; +import java.util.Map; + +/** + * Validates the contents of the CSAR package uploaded in SDC. + */ + +public interface Validator { + + /** + * + * @param contentHandler contains file and its data + * @param folderList folder structure inside the package + * @return errors Map of errors that occur + */ + Map<String, List<ErrorMessage>> validateContent(FileContentHandler contentHandler, List<String> folderList); +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactory.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactory.java new file mode 100644 index 0000000000..bc44496fef --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactory.java @@ -0,0 +1,45 @@ +/*- + * ============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.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.vendorsoftwareproduct.services.impl.etsi.ETSIService; +import org.openecomp.sdc.vendorsoftwareproduct.services.impl.etsi.ETSIServiceImpl; +import java.io.IOException; + +public class ValidatorFactory { + + private ValidatorFactory(){ + + } + + /** + * Returns a validator based on the contents of the csar package. + * + * @param contentMap the csar package + * @return Validator based on the contents of the csar package provided + * @throws IOException when metafile is invalid + */ + public static Validator getValidator(FileContentHandler contentMap) throws IOException{ + ETSIService etsiService = new ETSIServiceImpl(null); + return etsiService.isSol004WithToscaMetaDirectory(contentMap) ? new SOL004MetaDirectoryValidator() : new ONAPCsarValidator(); + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/exceptions/InvalidManifestMetadataException.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/exceptions/InvalidManifestMetadataException.java new file mode 100644 index 0000000000..137891c0c9 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/exceptions/InvalidManifestMetadataException.java @@ -0,0 +1,28 @@ +/*- + * ============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.vendorsoftwareproduct.impl.orchestration.exceptions; + +public class InvalidManifestMetadataException extends RuntimeException{ + + public InvalidManifestMetadataException(String message){ + super(message); + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java new file mode 100644 index 0000000000..bedf599cf5 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ONAPCsarValidatorTest.java @@ -0,0 +1,73 @@ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.common.utils.SdcCommon; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertTrue; + + +public class ONAPCsarValidatorTest { + + ONAPCsarValidator onapCsarValidator; + private FileContentHandler contentHandler; + private List<String> folderList; + + @Before + public void setUp() throws IOException{ + onapCsarValidator = new ONAPCsarValidator(); + contentHandler = new FileContentHandler(); + folderList = new ArrayList<>(); + + contentHandler.addFile("TOSCA-Metadata/TOSCA.meta", ValidatorUtil.getFileResource("/validation.files/metafile/nonSOL004WithMetaDirectoryCompliantMetaFile.meta")); + contentHandler.addFile("MainServiceTemplate.mf", ValidatorUtil.getFileResource("/validation.files/manifest/sampleManifest.mf")); + contentHandler.addFile(TestConstants.TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(TestConstants.SAMPLE_DEFINITION_FILE_PATH)); + } + + @Test + public void testGivenCSARPackage_withValidContent_thenNoErrorsReturned() { + assertExpectedErrors("Valid CSAR Package should have 0 errors", + onapCsarValidator.validateContent(contentHandler, folderList), 0); + } + + @Test + public void testGivenCSARPackage_withInvalidManifestFile_thenErrorsReturned() throws IOException{ + contentHandler = new FileContentHandler(); + contentHandler.addFile("TOSCA-Metadata/TOSCA.meta", ValidatorUtil.getFileResource("/validation.files/metafile/nonSOL004WithMetaDirectoryCompliantMetaFile.meta")); + contentHandler.addFile("MainServiceTemplate.mf", ValidatorUtil.getFileResource("/validation.files/manifest/invalidManifest.mf")); + contentHandler.addFile(TestConstants.TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(TestConstants.SAMPLE_DEFINITION_FILE_PATH)); + + assertExpectedErrors("CSAR package with invalid manifest file should have errors", onapCsarValidator.validateContent(contentHandler, folderList), 1); + + } + + @Test + public void testGivenCSARPackage_withUnwantedFolders_thenErrorsReturned(){ + + folderList.add("Files/"); + assertExpectedErrors("CSAR package with unwanted folders should fail with errors", onapCsarValidator.validateContent(contentHandler, folderList), 1); + } + + @Test + public void testGivenCSARPackage_withUnwantedFiles_thenErrorsReturned(){ + + contentHandler.addFile("ExtraFile.text", "".getBytes()); + assertExpectedErrors("CSAR package with unwanted files should fail with errors", + onapCsarValidator.validateContent(contentHandler, folderList), 1); + } + + private void assertExpectedErrors( String testCase, Map<String, List<ErrorMessage>> errors, int expectedErrors){ + if(expectedErrors > 0){ + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(testCase, errorMessages.size() == expectedErrors); + }else{ + assertTrue(testCase,errors.size() == expectedErrors); + } + } +}
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java new file mode 100644 index 0000000000..8584d482b4 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidatorTest.java @@ -0,0 +1,405 @@ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.core.utilities.file.FileContentHandler; +import org.openecomp.sdc.common.utils.SdcCommon; +import org.openecomp.sdc.datatypes.error.ErrorLevel; +import org.openecomp.sdc.datatypes.error.ErrorMessage; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertTrue; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.*; + +public class SOL004MetaDirectoryValidatorTest { + + private SOL004MetaDirectoryValidator sol004MetaDirectoryValidator; + private FileContentHandler handler; + private String metaFile; + + @Before + public void setUp(){ + sol004MetaDirectoryValidator = new SOL004MetaDirectoryValidator(); + handler = new FileContentHandler(); + metaFile = + "TOSCA-Meta-File-Version: 1.0\n"+ + "CSAR-Version: 1.1\n"+ + "Created-by: Vendor\n"+ + "Entry-Definitions: Definitions/MainServiceTemplate.yaml\n"+ + "Entry-Manifest: Definitions/MainServiceTemplate.mf\n"+ + "Entry-Change-Log: Artifacts/changeLog.text\n"; + } + + @Test + public void testGivenTOSCAMetaFile_whenEntryHasNoValue_thenErrorIsReturned() throws IOException{ + + String metaFileWithInvalidEntry = "TOSCA-Meta-File-Version: \n" + + "Entry-Definitions: Definitions/MainServiceTemplate.yaml"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFileWithInvalidEntry.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(TestConstants.SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + } + + @Test + public void testGivenTOSCAMeta_withAllSupportedEntries_thenNoErrorsReturned() throws IOException{ + + String entryTestFilePath = "Files/Tests"; + String entryLicenseFilePath = "Files/Licenses"; + + List<String> folderList = new ArrayList<>(); + folderList.add("Files/Tests/"); + folderList.add("Files/Licenses/"); + + metaFile = metaFile + + "Entry-Tests: "+ entryTestFilePath + "\n" + + "Entry-Licenses: "+ entryLicenseFilePath +"\n"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, "".getBytes()); + handler.addFile(entryTestFilePath, "".getBytes()); + handler.addFile(entryLicenseFilePath, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, folderList); + assertTrue(errors.size() == 0); + } + + @Test + public void testGivenTOSCAMeta_withUnsupportedEntry_thenWarningIsReturned(){ + + metaFile = "Entry-Events: Definitions/events.log"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + assertTrue(errorMessages.get(0).getLevel() == ErrorLevel.ERROR); + + } + + @Test + public void testGivenTOSCAMetaFile_withInvalidTOSCAMetaFileVersionAndCSARVersion_thenErrorIsReturned() throws IOException{ + + String metaFile = + "TOSCA-Meta-File-Version: " + Integer.MAX_VALUE + + "\nCSAR-Version: " + Integer.MAX_VALUE + + "\nCreated-by: Bilal Iqbal" + + "\nEntry-Definitions: Definitions/MainServiceTemplate.yaml" + + "\nEntry-Manifest: Definitions/MainServiceTemplate.mf"+ + "\nEntry-Change-Log: Artifacts/changeLog.text"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(TestConstants.SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 2); + } + + @Test + public void testGivenTOSCAMetaFile_withNonExistentFileReferenced_thenErrorsReturned(){ + + metaFile = metaFile + + "Entry-Tests: Files/Tests\n" + + "Entry-License: Files/Licenses\n"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 5); + } + + + @Test + public void testGivenDefinitionFile_whenValidImportStatementExist_thenNoErrorsReturned() throws IOException{ + + String definitionFileWithValidImports = "/validation.files/definition/definitionFileWithValidImports.yaml"; + + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + handler.addFile("Definitions/etsi_nfv_sol001_pnfd_2_5_1_types.yaml", ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(definitionFileWithValidImports)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertTrue(errors.size() == 0); + } + + @Test + public void testGivenDefinitionFile_whenMultipleDefinitionsImportStatementExist_thenNoErrorsReturned() throws IOException{ + + byte [] sampleDefinitionFile1 = ValidatorUtil.getFileResource("/validation.files/definition/sampleDefinitionFile1.yaml"); + byte [] sampleDefinitionFile2 = ValidatorUtil.getFileResource("/validation.files/definition/sampleDefinitionFile2.yaml"); + byte [] sampleDefinitionFile3 = ValidatorUtil.getFileResource("/validation.files/definition/sampleDefinitionFile3.yaml"); + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, sampleDefinitionFile1); + handler.addFile("Definitions/etsi_nfv_sol001_pnfd_2_5_1_types.yaml", sampleDefinitionFile2); + handler.addFile("Definitions/etsi_nfv_sol001_pnfd_2_5_2_types.yaml", sampleDefinitionFile3); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertTrue(errors.size() == 0); + } + + @Test + public void testGivenDefinitionFile_whenInvalidImportStatementExist_thenErrorIsReturned() throws IOException{ + + String definitionFileWithInvalidImports = "/validation.files/definition/definitionFileWithInvalidImport.yaml"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(definitionFileWithInvalidImports)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + } + + @Test + public void testGivenDefinitionFile_whenReferencedImportDoesNotExist_thenErrorIsReturned() throws IOException{ + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + handler.addFile("Definitions/etsi_nfv_sol001_pnfd_2_5_1_types.yaml", "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource("/validation.files/definition/sampleDefinitionFile2.yaml")); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + + } + + @Test + public void testGivenDefinitionFile_withInvalidYAML_thenErrorIsReturned() throws IOException{ + + String definitionFileWithInvalidYAML = "/validation.files/definition/invalidDefinitionFile.yaml"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_MANIFEST_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(definitionFileWithInvalidYAML)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + } + + @Test + public void testGivenManifestFile_withValidSourceAndNonManoSources_thenNoErrorIsReturned() throws IOException{ + + String nonManoSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/validManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(SAMPLE_SOURCE, "".getBytes()); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(nonManoSource, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertTrue(errors.size() == 0); + } + + @Test + public void testGivenManifestFile_withNonExistentSourceFile_thenErrorIsReturned() throws IOException{ + String nonManoSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/validManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, "".getBytes()); + handler.addFile(nonManoSource, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + } + + @Test + public void testGivenManifestFile_withInvalidData_thenErrorIsReturned() throws IOException{ + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/invalidManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(errors.size() == 1 && errorMessages.size() == 1); + } + + @Test + public void testGivenManifestAndDefinitionFile_withSameNames_thenNoErrorReturned() throws IOException { + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/sampleManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertTrue(errors.size() == 0); + } + + @Test + public void testGivenManifestAndMainDefinitionFile_withDifferentNames_thenErrorIsReturned() throws IOException { + metaFile = + "TOSCA-Meta-File-Version: 1.0\n"+ + "CSAR-Version: 1.1\n"+ + "Created-by: Vendor\n"+ + "Entry-Definitions: Definitions/MainServiceTemplate.yaml\n"+ + "Entry-Manifest: Definitions/MainServiceTemplate2.mf\n"+ + "Entry-Change-Log: Artifacts/changeLog.text\n"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile("Definitions/MainServiceTemplate2.mf", ValidatorUtil.getFileResource("/validation.files/manifest/sampleManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Main TOSCA definitions file and Manifest file with different name should return error", + errors, 1); + } + + @Test + public void testGivenManifestFile_withDifferentExtension_thenErrorIsReturned() throws IOException { + metaFile = + "TOSCA-Meta-File-Version: 1.0\n"+ + "CSAR-Version: 1.1\n"+ + "Created-by: Vendor\n"+ + "Entry-Definitions: Definitions/MainServiceTemplate.yaml\n"+ + "Entry-Manifest: Definitions/MainServiceTemplate.txt\n"+ + "Entry-Change-Log: Artifacts/changeLog.text\n"; + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile("Definitions/MainServiceTemplate.txt", ValidatorUtil.getFileResource("/validation.files/manifest/sampleManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + handler.addFile(SAMPLE_DEFINITION_IMPORT_FILE_PATH, "".getBytes()); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest file with different extension than .mf should return error", + errors, 1); + } + + @Test + public void testGivenManifestFile_withValidVnfMetadata_thenNoErrorsReturned() throws IOException{ + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/sampleManifest.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with valid vnf mandatory values should not return any errors", errors, 0); + } + + @Test + public void testGivenManifestFile_withValidPnfMetadata_thenNoErrorsReturned() throws IOException { + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/sampleManifest2.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with valid pnf mandatory values should not return any errors", errors, 0); + } + + @Test + public void testGivenManifestFile_withMetadataContainingMixedPnfVnfMetadata_thenErrorIsReturned() throws IOException { + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/manifestInvalidMetadata.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with mixed metadata should return error", errors, 1); + } + + + @Test + public void testGivenManifestFile_withMetadataMissingPnfOrVnfMandatoryEntries_thenErrorIsReturned() throws IOException{ + + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/manifestInvalidMetadata2.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with missing vnf or pnf mandatory entries should return error", errors, 1); + } + + @Test + public void testGivenManifestFile_withMetadataMissingMandatoryPnfEntries_thenErrorIsReturned() throws IOException{ + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/manifestInvalidMetadata4.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with metadata missing pnf mandatory entries should return error", errors, 3); + + } + + @Test + public void testGivenManifestFile_withMetadataMissingMandatoryVnfEntries_thenErrorIsReturned() throws IOException{ + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/manifestInvalidMetadata5.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with metadata missing vnf mandatory entries should return error", errors, 4); + + } + + @Test + public void testGivenManifestFile_withMetadataEntriesExceedingTheLimit_thenErrorIsReturned() throws IOException{ + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, ValidatorUtil.getFileResource("/validation.files/manifest/manifestInvalidMetadata3.mf")); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_DEFINITION_FILEPATH, ValidatorUtil.getFileResource(SAMPLE_DEFINITION_FILE_PATH)); + + Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); + assertExpectedErrors("Manifest with more than 4 metadata entries should return error", errors, 2); + } + + private void assertExpectedErrors( String testCase, Map<String, List<ErrorMessage>> errors, int expectedErrors){ + if(expectedErrors > 0){ + List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); + assertTrue(testCase, errorMessages.size() == expectedErrors); + }else{ + assertTrue(testCase,errors.size() == expectedErrors); + } + } +}
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/TestConstants.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/TestConstants.java new file mode 100644 index 0000000000..0a88ebc37d --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/TestConstants.java @@ -0,0 +1,25 @@ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; + +class TestConstants { + + + public static final String SAMPLE_DEFINITION_IMPORT_FILE_PATH = "Definitions/etsi_nfv_sol001_pnfd_2_5_1_types.yaml"; + public static final String SAMPLE_SOURCE = "Artifacts/Deployment/Events/RadioNode_pnf_v1.yaml"; + public static final String SAMPLE_DEFINITION_FILE_PATH = "/validation.files/definition/sampleDefinitionFile.yaml"; + public static final String SAMPLE_MANIFEST_FILE_PATH = "/validation.files/manifest/sampleManifest.mf"; + + public static final String ENTRY_DEFINITIONS = "Entry-Definitions"; + public static final String ENTRY_MANIFEST = "Entry-Manifest"; + public static final String ENTRY_CHANGE_LOG = "Entry-Change-Log"; + + public static final String ENTRY_SEPARATOR = ":"; + + public static final String TOSCA_DEFINITION_FILEPATH = "Definitions/MainServiceTemplate.yaml"; + public static final String TOSCA_MANIFEST_FILEPATH = "Definitions/MainServiceTemplate.mf"; + public static final String TOSCA_CHANGELOG_FILEPATH = "Artifacts/changeLog.text"; + public static final String TOSCA_METADATA_FILEPATH = "TOSCA-Metadata/TOSCA.meta"; + + private TestConstants(){ + + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java new file mode 100644 index 0000000000..287662283c --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorFactoryTest.java @@ -0,0 +1,88 @@ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.core.utilities.file.FileContentHandler; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.ENTRY_CHANGE_LOG; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.ENTRY_DEFINITIONS; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.ENTRY_MANIFEST; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.ENTRY_SEPARATOR; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_CHANGELOG_FILEPATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_DEFINITION_FILEPATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_MANIFEST_FILEPATH; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.TOSCA_METADATA_FILEPATH; + +public class ValidatorFactoryTest { + + private String metaFile; + private FileContentHandler handler; + + @Before + public void setUp(){ + handler = new FileContentHandler(); + metaFile = + "TOSCA-Meta-File-Version: 1.0\n" + + "CSAR-Version: 1.1\n" + + "Created-by: Bilal Iqbal\n"; + } + + @Test(expected = IOException.class) + public void testGivenEmptyMetaFile_thenIOExceptionIsThrown() throws IOException{ + handler.addFile(TOSCA_METADATA_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + + ValidatorFactory.getValidator(handler); + } + + @Test + public void testGivenEmptyBlock0_thenONAPCsarValidatorIsReturned() throws IOException{ + handler.addFile(TOSCA_METADATA_FILEPATH, " ".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_DEFINITION_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + + assertEquals(ONAPCsarValidator.class, ValidatorFactory.getValidator(handler).getClass()); + } + + + @Test + public void testGivenNonSOL004MetaDirectoryCompliantMetaFile_thenONAPCSARValidatorIsReturned() throws IOException{ + metaFile = metaFile + + ENTRY_DEFINITIONS + ENTRY_SEPARATOR + TOSCA_DEFINITION_FILEPATH; + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + + assertEquals(ONAPCsarValidator.class, ValidatorFactory.getValidator(handler).getClass()); + } + + @Test + public void testGivenSOL004MetaDirectoryCompliantMetafile_thenONAPCsarValidatorIsReturned() throws IOException{ + + metaFile = metaFile + + ENTRY_DEFINITIONS + ENTRY_SEPARATOR + TOSCA_DEFINITION_FILEPATH + "\n" + + ENTRY_MANIFEST + ENTRY_SEPARATOR + TOSCA_MANIFEST_FILEPATH + "\n" + + ENTRY_CHANGE_LOG + ENTRY_SEPARATOR + TOSCA_CHANGELOG_FILEPATH + "\n"; + handler.addFile(TOSCA_METADATA_FILEPATH, metaFile.getBytes(StandardCharsets.UTF_8)); + + assertEquals(SOL004MetaDirectoryValidator.class, ValidatorFactory.getValidator(handler).getClass()); + } + + @Test + public void testGivenMultiBlockMetadataWithSOL00CompliantMetaFile_thenSOL004MetaDirectoryValidatorReturned() throws IOException { + + handler.addFile(TOSCA_METADATA_FILEPATH, ValidatorUtil.getFileResource("/validation.files/metafile/metaFileWithMultipleBlocks.meta")); + handler.addFile(TOSCA_DEFINITION_FILEPATH, "".getBytes()); + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + handler.addFile(TOSCA_MANIFEST_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + + assertEquals(SOL004MetaDirectoryValidator.class, ValidatorFactory.getValidator(handler).getClass()); + + } + +}
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorUtil.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorUtil.java new file mode 100644 index 0000000000..91e3807a79 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ValidatorUtil.java @@ -0,0 +1,22 @@ +package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Provides util methods for Validation Test classes. + */ + +class ValidatorUtil { + + private ValidatorUtil(){ + + } + + public static byte[] getFileResource(String filePath) throws IOException{ + InputStream inputStream = ClassLoader.class.getClass().getResourceAsStream(filePath); + return IOUtils.toByteArray(inputStream); + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/definitionFileWithInvalidImport.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/definitionFileWithInvalidImport.yaml new file mode 100644 index 0000000000..432a86a985 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/definitionFileWithInvalidImport.yaml @@ -0,0 +1,6 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: example definition file for testing + +imports: + - file: diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/definitionFileWithValidImports.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/definitionFileWithValidImports.yaml new file mode 100644 index 0000000000..392a568c82 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/definitionFileWithValidImports.yaml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: example definition file for testing + +imports: + - etsi_nfv_sol001_pnfd_2_5_1_types.yaml + - file: etsi_nfv_sol001_pnfd_2_5_1_types.yaml + - repository: <some_repository> + - namespace_uri: <some_namespace_uri> + - definitionFile3: etsi_nfv_sol001_pnfd_2_5_1_types.yaml + - definitionFile4: etsi_nfv_sol001_pnfd_2_5_1_types.yaml + - definitionFile5: + file: etsi_nfv_sol001_pnfd_2_5_1_types.yaml + - definitionFile6: + file: etsi_nfv_sol001_pnfd_2_5_1_types.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/invalidDefinitionFile.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/invalidDefinitionFile.yaml new file mode 100644 index 0000000000..6a2df5ec70 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/invalidDefinitionFile.yaml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_simple_profile_yaml_1_1 +description: Sample yaml definition file for validation purpose + +node_types: + MyCompany.MyVnf.1_0.1_0: # node type of MyVnf + derived_from: tosca.nodes.nfv.VNF # this line has invalid tabbing + properties: + descriptor_id: + type: string + constraints: [ valid_values: [ b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 ] ] + default: b1bb0ce7-ebca-4fa7-95ed-4840d70a1177 + provider: + type: string + constraints: [ valid_values: [ MyCompany ] ] + default: MyCompany + product_name: + type: string + constraints: [ valid_values: [ MyVnf ] ] + default: Myvnf + software_version: + type: string + constraints: [ valid_values: [ '1.0' ] ] + default: '1.0' + descriptor_version: + type: string + constraints: [ valid_values: [ '1.0' ] ] + default: '1.0' + flavour_id: + type: string + constraints: [ valid_values: [ simple ] ] #only one and only allowed one DF in this example + default: simple + flavour_description: + type: string + vnfm_info: + type: list + interfaces: + Nfv: + instantiate: + inputs: + parameter_1: + type: string + required: false + default: value_1 + parameter_2: + type: string + required: false + default: value_2 + terminate: + implementation: terminate.workbook.mistral.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile.yaml new file mode 100644 index 0000000000..cab7950763 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile.yaml @@ -0,0 +1,4 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: example definition file for testing + diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile1.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile1.yaml new file mode 100644 index 0000000000..3187f4f292 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile1.yaml @@ -0,0 +1,7 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: example definition file for testing + +imports: + - etsi_nfv_sol001_pnfd_2_5_1_types.yaml + diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile2.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile2.yaml new file mode 100644 index 0000000000..0b7f774140 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile2.yaml @@ -0,0 +1,7 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: example definition file for testing + +imports: + - etsi_nfv_sol001_pnfd_2_5_2_types.yaml + diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile3.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile3.yaml new file mode 100644 index 0000000000..4df199d767 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/definition/sampleDefinitionFile3.yaml @@ -0,0 +1,6 @@ +tosca_definitions_version: tosca_simple_yaml_1_2 + +description: example definition file for testing + +imports: + - etsi_nfv_sol001_pnfd_2_5_1_types.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/invalidManifest.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/invalidManifest.mf new file mode 100644 index 0000000000..08e211c8d8 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/invalidManifest.mf @@ -0,0 +1,3 @@ +Source: #This should start with metadata: + + diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata.mf new file mode 100644 index 0000000000..53395c9f34 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata.mf @@ -0,0 +1,7 @@ +metadata: + pnf_product_name: RadioNode + vnf_provider_id: Bilal Iqbal + pnf_package_version: 1.0 + vnf_release_date_time: 2019-12-14T11:25:00+00:00 + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata2.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata2.mf new file mode 100644 index 0000000000..64fcdc247b --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata2.mf @@ -0,0 +1,7 @@ +metadata: + invalid_product_name: RadioNode + invalid_provider_id: Bilal Iqbal + invalid_package_version: 1.0 + invalid_release_date_time: 2019-12-14T11:25:00+00:00 + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata3.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata3.mf new file mode 100644 index 0000000000..ea92856e43 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata3.mf @@ -0,0 +1,11 @@ +metadata: + pnf_product_name: RadioNode + pnf_provider_id: Bilal Iqbal + pnf_package_version: 1.0 + pnf_release_date_time: 2019-12-14T11:25:00+00:00 + vnf_product_name: RadioNode + vnf_provider_id: Bilal Iqbal + vnf_package_version: 1.0 + vnf_release_date_time: 2019-12-14T11:26:00+00:00 + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata4.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata4.mf new file mode 100644 index 0000000000..bce6beef01 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata4.mf @@ -0,0 +1,5 @@ +metadata: + pnf_product_name: RadioNode + pnf_release_date_time: 2019-12-14T11:25:00+00:00 + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata5.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata5.mf new file mode 100644 index 0000000000..aabbd470f7 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/manifestInvalidMetadata5.mf @@ -0,0 +1,4 @@ +metadata: + vnf_product_name: RadioNode + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/sampleManifest.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/sampleManifest.mf new file mode 100644 index 0000000000..a7aebd6cae --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/sampleManifest.mf @@ -0,0 +1,7 @@ +metadata: + vnf_product_name: RadioNode + vnf_provider_id: Bilal Iqbal + vnf_package_version: 1.0 + vnf_release_date_time: 2019-12-14T11:25:00+00:00 + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/sampleManifest2.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/sampleManifest2.mf new file mode 100644 index 0000000000..cfdf539be5 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/sampleManifest2.mf @@ -0,0 +1,7 @@ +metadata: + pnf_product_name: RadioNode + pnf_provider_id: Bilal Iqbal + pnf_package_version: 1.0 + pnf_release_date_time: 2019-12-14T11:25:00+00:00 + +Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/validManifest.mf b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/validManifest.mf new file mode 100644 index 0000000000..f34feafdf7 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/manifest/validManifest.mf @@ -0,0 +1,11 @@ +metadata: + pnf_product_name: RadioNode + pnf_provider_id: Bilal Iqbal + pnf_package_version: 1.0 + pnf_release_date_time: 2019-12-14T11:25:00+00:00 + +Source: Artifacts/Deployment/Events/RadioNode_pnf_v1.yaml + +non_mano_artifact_sets: + onap_pm_events: + Source: Artifacts/Deployment/Measurements/PM_Dictionary.yaml
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/metafile/metaFileWithMultipleBlocks.meta b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/metafile/metaFileWithMultipleBlocks.meta new file mode 100644 index 0000000000..38440a2133 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/metafile/metaFileWithMultipleBlocks.meta @@ -0,0 +1,10 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-by: Bilal Iqbal +Entry-Definitions: Definitions/MainServiceTemplate.yml +Entry-Manifest: Definitions/MainServiceTemplate.mf +Entry-Change-Log: Definitions/changeLog.text + +Entry-Definitions: Definitions/MainServiceTemplate2.yml +Entry-Manifest: Definitions/MainServiceTemplate2.mf +Entry-Change-Log: Definitions/changeLog2.text
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/metafile/nonSOL004WithMetaDirectoryCompliantMetaFile.meta b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/metafile/nonSOL004WithMetaDirectoryCompliantMetaFile.meta new file mode 100644 index 0000000000..eea0795386 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/metafile/nonSOL004WithMetaDirectoryCompliantMetaFile.meta @@ -0,0 +1,4 @@ +TOSCA-Meta-File-Version: 1.0 +CSAR-Version: 1.1 +Created-by: Bilal Iqbal +Entry-Definitions: Definitions/MainServiceTemplate.yaml diff --git a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java index 6cb82b5d4d..095e5b49c2 100644 --- a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java +++ b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java @@ -32,9 +32,18 @@ public enum Messages { MANIFEST_INVALID_LINE("Manifest contains invalid line : %s"), MANIFEST_NO_METADATA("Manifest must contain metadata"), MANIFEST_NO_SOURCES("Manifest must contain Source"), + MANIFEST_METADATA_MISSING_ENTRY("Manifest metadata missing entry %s"), + MANIFEST_INVALID_NAME("Manifest file has a different name than main TOSCA definitions file"), + MANIFEST_INVALID_EXT("Manifest file does not have extension \".mf\" "), + MANIFEST_METADATA_INVALID_ENTRY("Manifest metadata should only have pnf or vnf entries"), + MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT("Manifest metadata must only have the required number of values [%s]"), MANIFEST_EMPTY("Manifest must contain data"), MANIFEST_PARSER_INTERNAL("Invalid manifest file"), METADATA_PARSER_INTERNAL("Invalid Metadata file"), + METADATA_MISSING_OPTIONAL_FOLDERS("Missing folder %s in package"), + METADATA_UNSUPPORTED_ENTRY("Following entry not supported in TOSCA.meta %s"), + METADATA_INVALID_VALUE("Invalid value %s in TOSCA.meta file"), + METADATA_MISSING_ENTRY("TOSCA.meta file missing entry %s"), METADATA_NO_ENTRY_DEFINITIONS("TOSCA.meta must contain Entry Definitions"), METADATA_INVALID_ENTRY_DEFINITIONS("TOSCA.meta must contain key:value entries"), FAILED_TO_VALIDATE_METADATA("Failed to validate metadata file"), @@ -93,6 +102,12 @@ public enum Messages { CSAR_MANIFEST_FILE_NOT_EXIST("CSAR manifest file does not exist"), CSAR_FAILED_TO_READ("CSAR file is not readable"), TOSCA_PARSING_FAILURE("Invalid tosca file. Error code : %s, Error message : %s/"), + + /*definition errors*/ + MISSING_DEFINITION_FILE("Definition file %s does not exist"), + MISSING_IMPORT_FILE("Package must contain the referenced import file %s"), + INVALID_IMPORT_STATEMENT("Definition file contains an invalid import statement"), + /* content errors*/ INVALID_YAML_FORMAT("Invalid YAML format - %s"), INVALID_YAML_FORMAT_REASON("Invalid YAML format Problem - [%s]"), diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIService.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIService.java index 69ce97efc5..d5dab46533 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIService.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-api/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIService.java @@ -22,16 +22,19 @@ package org.openecomp.sdc.vendorsoftwareproduct.services.impl.etsi; import org.openecomp.core.utilities.file.FileContentHandler; import org.openecomp.sdc.tosca.csar.Manifest; +import java.io.IOException; public interface ETSIService { + /** * Checks package structure is CSAR with TOSCA-Metadata directory according to SOL004 v2.5.1 * and contains mandatory Entries in Tosca.meta * @param handler contains csar artifacts * @return true if all condition matched, false otherwise + * @throws IOException when TOSCA.meta file is invalid */ - boolean isSol004WithToscaMetaDirectory(FileContentHandler handler); + boolean isSol004WithToscaMetaDirectory(FileContentHandler handler) throws IOException; /** * Update file structure. Moves non mano files to Artifacts/Deployment/non mano key location diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImpl.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImpl.java index b3002abf6e..9984df1ccc 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImpl.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImpl.java @@ -30,11 +30,16 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; -import java.util.Optional; import org.openecomp.sdc.tosca.csar.Manifest; +import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata; +import org.openecomp.sdc.tosca.csar.ToscaMetadata; -import static org.openecomp.sdc.tosca.csar.CSARConstants.*; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_CHANGE_LOG; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_DEFINITIONS; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_MANIFEST; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ORIG_PATH_FILE_NAME; +import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME; public class ETSIServiceImpl implements ETSIService { @@ -55,9 +60,9 @@ public class ETSIServiceImpl implements ETSIService { } @Override - public boolean isSol004WithToscaMetaDirectory(FileContentHandler handler) { + public boolean isSol004WithToscaMetaDirectory(FileContentHandler handler) throws IOException { Map<String, byte[]> templates = handler.getFiles(); - return isMetaFilePresent(templates) && hasMetaMandatoryEntries(templates); + return isMetaFilePresent(templates) && hasMetaMandatoryEntries(getMetadata(handler)); } @Override @@ -69,6 +74,15 @@ public class ETSIServiceImpl implements ETSIService { } } + private InputStream getMetadata(FileContentHandler contentHandler) throws IOException{ + if(contentHandler.containsFile(TOSCA_META_PATH_FILE_NAME)){ + return contentHandler.getFileContent(TOSCA_META_PATH_FILE_NAME); + }else if(contentHandler.containsFile(TOSCA_META_ORIG_PATH_FILE_NAME)){ + return contentHandler.getFileContent(TOSCA_META_ORIG_PATH_FILE_NAME); + } + throw new IOException("TOSCA.meta file does not exist"); + } + private void updateNonManoLocation(FileContentHandler handler, String nonManoKey, List<String> sources) { Map<String, byte[]> files = handler.getFiles(); for (String key : sources) { @@ -98,15 +112,12 @@ public class ETSIServiceImpl implements ETSIService { return key.substring(key.lastIndexOf('/') + 1); } - private boolean hasMetaMandatoryEntries(Map<String, byte[]> templates) { - Optional<byte[]> meta = templates.entrySet().stream().filter(e -> e.getKey().equals(TOSCA_META_PATH_FILE_NAME) - || e.getKey().equals(TOSCA_META_ORIG_PATH_FILE_NAME)).findFirst().map(Map.Entry::getValue); - if (!meta.isPresent()) { - return false; - } - String metaContent = new String(meta.get(), StandardCharsets.UTF_8); - return metaContent.contains(TOSCA_META_ENTRY_DEFINITIONS) && metaContent.contains(TOSCA_META_ENTRY_MANIFEST) - && metaContent.contains(TOSCA_META_ENTRY_CHANGE_LOG); + private boolean hasMetaMandatoryEntries(InputStream metadataInputStream) throws IOException { + + ToscaMetadata toscaMetadata = OnboardingToscaMetadata.parseToscaMetadataFile(metadataInputStream); + Map<String, String> metaDataEntries = toscaMetadata.getMetaEntries(); + return metaDataEntries.containsKey(TOSCA_META_ENTRY_DEFINITIONS) && metaDataEntries.containsKey(TOSCA_META_ENTRY_MANIFEST) + && metaDataEntries.containsKey(TOSCA_META_ENTRY_CHANGE_LOG); } private boolean isMetaFilePresent(Map<String, byte[]> handler) { diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImplTest.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImplTest.java index ae69415f1d..2dc37f17e4 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImplTest.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/etsi/ETSIServiceImplTest.java @@ -49,28 +49,28 @@ public class ETSIServiceImplTest { } @Test - public void testIsSol004TrueOrigin() { + public void testIsSol004TrueOrigin() throws IOException { FileContentHandler fileContentHandler = new FileContentHandler(); fileContentHandler.addFile("TOSCA-Metadata/TOSCA.meta.original", sol004MetaFile.getBytes(StandardCharsets.UTF_8)); assertTrue(etsiService.isSol004WithToscaMetaDirectory(fileContentHandler)); } @Test - public void testIsSol004True() { + public void testIsSol004True() throws IOException { FileContentHandler fileContentHandler = new FileContentHandler(); fileContentHandler.addFile("TOSCA-Metadata/TOSCA.meta", sol004MetaFile.getBytes(StandardCharsets.UTF_8)); assertTrue(etsiService.isSol004WithToscaMetaDirectory(fileContentHandler)); } @Test - public void testIsSol004False() { + public void testIsSol004False() throws IOException { FileContentHandler fileContentHandler = new FileContentHandler(); fileContentHandler.addFile("TOSCA-Metadata/TOSCA.meta.original", metaFile.getBytes(StandardCharsets.UTF_8)); assertFalse(etsiService.isSol004WithToscaMetaDirectory(fileContentHandler)); } @Test - public void testIsSol004FalseWithNull() { + public void testIsSol004FalseWithNull() throws IOException { FileContentHandler fileContentHandler = new FileContentHandler(); assertFalse(etsiService.isSol004WithToscaMetaDirectory(fileContentHandler)); } diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/main/java/org/openecomp/core/converter/ServiceTemplateReaderService.java b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/main/java/org/openecomp/core/converter/ServiceTemplateReaderService.java index 1bc97b4d69..3b861e425d 100644 --- a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/main/java/org/openecomp/core/converter/ServiceTemplateReaderService.java +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-api/src/main/java/org/openecomp/core/converter/ServiceTemplateReaderService.java @@ -1,5 +1,27 @@ + +/*- + * ============LICENSE_START======================================================= + * Modification 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.core.converter; +import java.util.List; import java.util.Map; public interface ServiceTemplateReaderService { @@ -21,4 +43,6 @@ public interface ServiceTemplateReaderService { Map<String, Object> getOutputs(); Map<String, Object> getSubstitutionMappings(); + + List<Object> getImports(); } diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/services/ServiceTemplateReaderServiceImpl.java b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/services/ServiceTemplateReaderServiceImpl.java index b691d83267..44b0c80e24 100644 --- a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/services/ServiceTemplateReaderServiceImpl.java +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/services/ServiceTemplateReaderServiceImpl.java @@ -1,9 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * Modification 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.core.impl.services; import org.onap.sdc.tosca.services.YamlUtil; import org.openecomp.core.converter.ServiceTemplateReaderService; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -26,6 +48,12 @@ public class ServiceTemplateReaderServiceImpl implements ServiceTemplateReaderSe } @Override + public List<Object> getImports(){ + return Objects.isNull(this.readServiceTemplate.get("imports")) ? + new ArrayList<>() : (List<Object>) this.readServiceTemplate.get("imports"); + } + + @Override public Object getMetadata(){ return this.readServiceTemplate.get(metadata); } 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 94786fe0df..97e7809828 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 @@ -1,5 +1,6 @@ /* * Copyright © 2016-2017 European Support Limited + * 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. @@ -27,18 +28,33 @@ public class CSARConstants { public static final String MAIN_SERVICE_TEMPLATE_MF_FILE_NAME = "MainServiceTemplate.mf"; public static final String MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME = "MainServiceTemplate.yaml"; public static final String TOSCA_META_PATH_FILE_NAME="TOSCA-Metadata/TOSCA.meta"; + public static final String TOSCA_META_FILE_VERSION_ENTRY = "TOSCA-Meta-File-Version"; + 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_ENTRY_MANIFEST="Entry-Manifest"; public static final String TOSCA_META_ENTRY_CHANGE_LOG="Entry-Change-Log"; + public static final String TOSCA_META_ENTRY_TESTS = "Entry-Tests"; + public static final String TOSCA_META_ENTRY_LICENSES= "Entry-Licenses"; public static final ImmutableSet<String> ELIGIBLE_FILES = of(MAIN_SERVICE_TEMPLATE_MF_FILE_NAME,MAIN_SERVICE_TEMPLATE_YAML_FILE_NAME); - + public static final ImmutableSet<String> MANIFEST_PNF_METADATA = + of("pnf_provider_id", "pnf_product_name", "pnf_release_date_time", "pnf_package_version"); + public static final ImmutableSet<String> MANIFEST_VNF_METADATA = + of("vnf_provider_id", "vnf_product_name", "vnf_release_date_time", "vnf_package_version"); + 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 SEPERATOR_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"; + public static final String CSAR_VERSION_1_0 = "1.0"; + public static final String CSAR_VERSION_1_1 = "1.1"; + public static final ImmutableSet<String> NON_FILE_IMPORT_ATTRIBUTES = + ImmutableSet.of("repository", "namespace_uri", "namespace_prefix"); + private CSARConstants() { } diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingManifest.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingManifest.java index 8858128b38..efa7e0aa1a 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingManifest.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/csar/OnboardingManifest.java @@ -133,11 +133,12 @@ public class OnboardingManifest implements Manifest{ } String[] metaSplit = line.split(SEPERATOR_MF_ATTRIBUTE); if (metaSplit.length < 2){ + reportError(line); return; } if (!metaSplit[0].equals(SOURCE_MF_ATTRIBUTE) && !metaSplit[0].equals(NON_MANO_MF_ATTRIBUTE)){ String value = line.substring((metaSplit[0] + SEPERATOR_MF_ATTRIBUTE).length()).trim(); - metadata.put(metaSplit[0],value); + metadata.put(metaSplit[0].trim(),value.trim()); processMetadata(iterator); } else { 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 b4d7f84ca4..6dd6979751 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 @@ -56,6 +56,9 @@ public class OnboardingToscaMetadata implements ToscaMetadata{ * @throws IOException */ public static ToscaMetadata parseToscaMetadataFile(InputStream st) throws IOException { + if(st == null) { + throw new IOException(Messages.METADATA_PARSER_INTERNAL.getErrorMessage()); + } OnboardingToscaMetadata meta = new OnboardingToscaMetadata(); List<String> metadataLines = IOUtils.readLines(st, "utf-8"); for (String line : metadataLines) { |