diff options
author | andre.schmid <andre.schmid@est.tech> | 2019-07-24 08:57:20 +0000 |
---|---|---|
committer | Ofir Sonsino <ofir.sonsino@intl.att.com> | 2019-08-06 09:03:52 +0000 |
commit | 031db8630dda9706e22aa3bbdf0f2dfba33fb86e (patch) | |
tree | 5c0d076c02c6d67e01a154fab5245692232ee89a | |
parent | d7d87dc3a647e924bcf0e05e60c18f70cba3ed7b (diff) |
Validate PM Dictionary and VES Events YAML Files
Validate, during the package onboarding, YAML files declared in the
manifest as type onap_ves_events or onap_pm_dictionary under
non_mano_artifact_sets. Check if the file is not empty, if has a yaml
extension and if it has a valid yaml content.
Change-Id: I260d0f5355e9e77b6499f553f8aa9f7e6d0693da
Issue-ID: SDC-2475
Signed-off-by: andre.schmid <andre.schmid@est.tech>
13 files changed, 792 insertions, 130 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 3a687f774c..1dbb1d7e8e 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 @@ -209,14 +209,20 @@ <version>${bouncycastle.version}</version> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> - <version>${hamcrest-all.version}</version> + <version>${hamcrest.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/NonManoArtifactType.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/NonManoArtifactType.java new file mode 100644 index 0000000000..53ffb0b608 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/NonManoArtifactType.java @@ -0,0 +1,42 @@ +/* + * ============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; + +/** + * Stores non mano artifact types. + */ +public enum NonManoArtifactType { + ONAP_VES_EVENTS("onap_ves_events"), + ONAP_PM_DICTIONARY("onap_pm_dictionary"), + ONAP_YANG_MODULES("onap_yang_modules"), + ONAP_ANSIBLE_PLAYBOOKS("onap_ansible_playbooks"), + ONAP_SCRIPTS("onap_scripts"), + ONAP_OTHERS("onap_others"); + + private final String type; + + NonManoArtifactType(final String type) { + this.type = type; + } + + public String getType() { + return type; + } +} diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java index 2bd28b389b..bed3a9b128 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/SOL004MetaDirectoryValidator.java @@ -20,7 +20,9 @@ package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation; +import java.io.InputStream; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.io.FilenameUtils; import org.openecomp.core.impl.ToscaDefinitionImportHandler; import org.openecomp.core.utilities.file.FileContentHandler; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; @@ -37,7 +39,6 @@ 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.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -46,6 +47,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import org.yaml.snakeyaml.Yaml; import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_0; import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_1; @@ -66,6 +68,8 @@ 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; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_TYPE_PNF; import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_TYPE_VNF; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_PM_DICTIONARY; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_VES_EVENTS; /** * Validates the contents of the package to ensure it complies with the "CSAR with TOSCA-Metadata directory" structure @@ -78,58 +82,73 @@ class SOL004MetaDirectoryValidator implements Validator { private static final String MANIFEST_SOURCE = "Source"; private static final String MANIFEST_NON_MANO_SOURCE = "Non-MANO Source"; private final List<ErrorMessage> errorsByFile = new ArrayList<>(); + private FileContentHandler contentHandler; + private List<String> folderList; + private ToscaMetadata toscaMetadata; @Override - public Map<String, List<ErrorMessage>> validateContent(FileContentHandler contentHandler, List<String> folderList) { - validateMetaFile(contentHandler, folderList); - return Collections.unmodifiableMap(getAnyValidationErrors()); + public Map<String, List<ErrorMessage>> validateContent(final FileContentHandler contentHandler + , final List<String> folderList) { + this.contentHandler = contentHandler; + this.folderList = folderList; + parseToscaMetadata(); + verifyMetadataFile(); + return Collections.unmodifiableMap(getAnyValidationErrors()); } - private void validateMetaFile(FileContentHandler contentHandler, List<String> folderList) { + /** + * Parses the {@link org.openecomp.sdc.tosca.csar.CSARConstants#TOSCA_META_PATH_FILE_NAME} file + */ + private void parseToscaMetadata() { 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){ + toscaMetadata = + OnboardingToscaMetadata + .parseToscaMetadataFile(contentHandler.getFileContent(TOSCA_META_PATH_FILE_NAME)); + } catch (final IOException e) { reportError(ErrorLevel.ERROR, Messages.METADATA_PARSER_INTERNAL.getErrorMessage()); LOGGER.error(Messages.METADATA_PARSER_INTERNAL.getErrorMessage(), e.getMessage(), e); } } - private void verifyManifestNameAndExtension(ToscaMetadata toscaMetadata) { - Map<String, String> entries = toscaMetadata.getMetaEntries(); - String manifestFileName = getFileName(entries.get(TOSCA_META_ETSI_ENTRY_MANIFEST)); - String manifestExtension = getFileExtension(entries.get(TOSCA_META_ETSI_ENTRY_MANIFEST)); - String mainDefinitionFileName= getFileName(entries.get(TOSCA_META_ENTRY_DEFINITIONS)); - if(!(TOSCA_MANIFEST_FILE_EXT).equals(manifestExtension)){ + private void verifyMetadataFile() { + if (toscaMetadata.isValid() && hasETSIMetadata()) { + verifyManifestNameAndExtension(); + handleMetadataEntries(); + } else { + errorsByFile.addAll(toscaMetadata.getErrors()); + } + } + + private void verifyManifestNameAndExtension() { + final Map<String, String> entries = toscaMetadata.getMetaEntries(); + final String manifestFileName = getFileName(entries.get(TOSCA_META_ETSI_ENTRY_MANIFEST)); + final String manifestExtension = getFileExtension(entries.get(TOSCA_META_ETSI_ENTRY_MANIFEST)); + final String mainDefinitionFileName = getFileName(entries.get(TOSCA_META_ENTRY_DEFINITIONS)); + if (!(TOSCA_MANIFEST_FILE_EXT).equals(manifestExtension)) { reportError(ErrorLevel.ERROR, Messages.MANIFEST_INVALID_EXT.getErrorMessage()); } - if(!mainDefinitionFileName.equals(manifestFileName)){ + if (!mainDefinitionFileName.equals(manifestFileName)) { reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_INVALID_NAME.getErrorMessage(), manifestFileName, mainDefinitionFileName)); } } - public String getFileExtension(String filePath){ - return filePath.substring(filePath.lastIndexOf('.') + 1); + private String getFileExtension(final String filePath) { + return FilenameUtils.getExtension(filePath); } - private String getFileName(String filePath){ - return filePath.substring(filePath.lastIndexOf('/') + 1, filePath.lastIndexOf('.')); + private String getFileName(final String filePath) { + return FilenameUtils.getBaseName(filePath); } - private boolean hasETSIMetadata(ToscaMetadata toscaMetadata){ - Map<String, String> entries = toscaMetadata.getMetaEntries(); + private boolean hasETSIMetadata(){ + final 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) { + private boolean hasEntry(final Map<String, String> entries, final String mandatoryEntry) { if (!entries.containsKey(mandatoryEntry)) { reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_ENTRY.getErrorMessage(),mandatoryEntry)); return false; @@ -137,15 +156,15 @@ class SOL004MetaDirectoryValidator implements Validator { return true; } - private void handleMetadataEntries(FileContentHandler contentHandler, List<String> folderList, ToscaMetadata toscaMetadata) { - for(Map.Entry entry: toscaMetadata.getMetaEntries().entrySet()){ - handleEntry(contentHandler, folderList, toscaMetadata, entry); + private void handleMetadataEntries() { + for(final Map.Entry entry: toscaMetadata.getMetaEntries().entrySet()){ + handleEntry(entry); } } - private void handleEntry(FileContentHandler contentHandler, List<String> folderList, ToscaMetadata toscaMetadata, Map.Entry entry) { - String key = (String) entry.getKey(); - String value = (String) entry.getValue(); + private void handleEntry(final Map.Entry<String, String> entry) { + final String key = entry.getKey(); + final String value = entry.getValue(); switch (key){ case TOSCA_META_FILE_VERSION_ENTRY: case TOSCA_META_CSAR_VERSION_ENTRY: @@ -153,63 +172,62 @@ class SOL004MetaDirectoryValidator implements Validator { verifyMetadataEntryVersions(key, value); break; case TOSCA_META_ENTRY_DEFINITIONS: - validateDefinitionFile(contentHandler, value); + validateDefinitionFile(value); break; case TOSCA_META_ETSI_ENTRY_MANIFEST: - validateManifestFile(contentHandler, value); + validateManifestFile(value); break; case TOSCA_META_ETSI_ENTRY_CHANGE_LOG: - validateChangeLog(contentHandler, value); + validateChangeLog(value); break; case TOSCA_META_ETSI_ENTRY_TESTS: case TOSCA_META_ETSI_ENTRY_LICENSES: - validateOtherEntries(folderList, entry, contentHandler, toscaMetadata); + validateOtherEntries(entry); break; case TOSCA_META_ETSI_ENTRY_CERTIFICATE: - validateOtherEntries(folderList, value); + validateOtherEntries(value); break; default: - errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, String.format(Messages.METADATA_UNSUPPORTED_ENTRY.getErrorMessage(), entry))); + reportError(ErrorLevel.ERROR, Messages.METADATA_UNSUPPORTED_ENTRY.formatMessage(entry.toString())); LOGGER.warn(Messages.METADATA_UNSUPPORTED_ENTRY.getErrorMessage(), entry); break; } } - private void validateOtherEntries(List<String> folderList, Map.Entry entry, FileContentHandler contentHandler, ToscaMetadata toscaMetadata) { - String manifestFile = toscaMetadata.getMetaEntries().get(TOSCA_META_ETSI_ENTRY_MANIFEST); + private void validateOtherEntries(final Map.Entry entry) { + final String manifestFile = toscaMetadata.getMetaEntries().get(TOSCA_META_ETSI_ENTRY_MANIFEST); if(verifyFileExists(contentHandler.getFileList(), manifestFile)){ - Manifest onboardingManifest = new SOL004ManifestOnboarding(); + final Manifest onboardingManifest = new SOL004ManifestOnboarding(); onboardingManifest.parse(contentHandler.getFileContent(manifestFile)); - Optional<ResourceTypeEnum> resourceType = onboardingManifest.getType(); - if(resourceType.isPresent() && resourceType.get() == ResourceTypeEnum.VF){ - String value = (String) entry.getValue(); - validateOtherEntries(folderList, value); - }else{ - String key = (String) entry.getKey(); + final Optional<ResourceTypeEnum> resourceType = onboardingManifest.getType(); + if (resourceType.isPresent() && resourceType.get() == ResourceTypeEnum.VF){ + final String value = (String) entry.getValue(); + validateOtherEntries(value); + } else { + final String key = (String) entry.getKey(); reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_INVALID_PNF_METADATA.getErrorMessage(), key)); } } } - - private void verifyMetadataEntryVersions(String key, String version) { + private void verifyMetadataEntryVersions(final String key, final String version) { if(!(isValidTOSCAVersion(key,version) || isValidCSARVersion(key, version) || TOSCA_META_CREATED_BY_ENTRY.equals(key))) { errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, String.format(Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version))); LOGGER.error("{}: key {} - value {} ", Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version); } } - private boolean isValidTOSCAVersion(String key, String version){ + private boolean isValidTOSCAVersion(final String key, final String version){ return TOSCA_META_FILE_VERSION_ENTRY.equals(key) && TOSCA_META_FILE_VERSION.equals(version); } - private boolean isValidCSARVersion(String value, String version){ + private boolean isValidCSARVersion(final String value, final String version){ return TOSCA_META_CSAR_VERSION_ENTRY.equals(value) && (CSAR_VERSION_1_1.equals(version) || CSAR_VERSION_1_0.equals(version)); } - private void validateDefinitionFile(final FileContentHandler contentHandler, final String filePath) { + private void validateDefinitionFile(final String filePath) { final Set<String> existingFiles = contentHandler.getFileList(); if (verifyFileExists(existingFiles, filePath)) { @@ -224,68 +242,67 @@ class SOL004MetaDirectoryValidator implements Validator { } } - private boolean verifyFileExists(Set<String> existingFiles, String filePath){ + private boolean verifyFileExists(final Set<String> existingFiles, final String filePath) { return existingFiles.contains(filePath); } - private void validateManifestFile(FileContentHandler contentHandler, String filePath){ + private void validateManifestFile(final String filePath) { final Set<String> existingFiles = contentHandler.getFileList(); if (verifyFileExists(existingFiles, filePath)) { - Manifest onboardingManifest = new SOL004ManifestOnboarding(); + final Manifest onboardingManifest = new SOL004ManifestOnboarding(); onboardingManifest.parse(contentHandler.getFileContent(filePath)); - if(onboardingManifest.isValid()){ + if (onboardingManifest.isValid()) { try { verifyManifestMetadata(onboardingManifest.getMetadata()); - }catch (InvalidManifestMetadataException e){ - reportError(ErrorLevel.ERROR, e.getMessage()); - LOGGER.error(e.getMessage(), e); - } - verifyManifestSources(existingFiles, onboardingManifest); - }else{ - List<String> manifestErrors = onboardingManifest.getErrors(); - for(String error: manifestErrors){ - reportError(ErrorLevel.ERROR, error); + } catch (final InvalidManifestMetadataException e) { + reportError(ErrorLevel.ERROR, e.getMessage()); + LOGGER.error(e.getMessage(), e); } + verifyManifestSources(onboardingManifest); + } else { + final List<String> manifestErrors = onboardingManifest.getErrors(); + manifestErrors.forEach(error -> reportError(ErrorLevel.ERROR, error)); } - }else { + } else { reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_NOT_FOUND.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(), + private void verifyManifestMetadata(final Map<String, String> metadata) { + if (metadata.size() != MANIFEST_METADATA_LIMIT) { + reportError(ErrorLevel.ERROR, + String.format(Messages.MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT.getErrorMessage(), MANIFEST_METADATA_LIMIT)); } - if(isPnfMetadata(metadata)){ + if (isPnfMetadata(metadata)) { handlePnfMetadataEntries(metadata); - }else { + } else { handleVnfMetadataEntries(metadata); } } - private boolean isPnfMetadata(Map<String, String> metadata) { - String metadataType = ""; - for(String key: metadata.keySet()) { - if(metadataType.isEmpty()){ - metadataType = key.contains(TOSCA_TYPE_PNF) ? TOSCA_TYPE_PNF : TOSCA_TYPE_VNF; - }else if(!key.contains(metadataType)){ - throw new InvalidManifestMetadataException(Messages.MANIFEST_METADATA_INVALID_ENTRY.getErrorMessage()); - } + private boolean isPnfMetadata(final Map<String, String> metadata) { + final String firstMetadataDefinition = metadata.keySet().iterator().next(); + final String expectedMetadataType = + firstMetadataDefinition.contains(TOSCA_TYPE_PNF) ? TOSCA_TYPE_PNF : TOSCA_TYPE_VNF; + if (metadata.keySet().stream() + .anyMatch((final String metadataEntry) -> !metadataEntry.contains(expectedMetadataType))) { + throw new InvalidManifestMetadataException(Messages.MANIFEST_METADATA_INVALID_ENTRY.getErrorMessage()); } - return TOSCA_TYPE_PNF.equals(metadataType); + + return TOSCA_TYPE_PNF.equals(expectedMetadataType); } - private void handleVnfMetadataEntries(Map<String, String> metadata) { - for (String requiredVnfEntry : MANIFEST_VNF_METADATA) { + private void handleVnfMetadataEntries(final Map<String, String> metadata) { + for (final String requiredVnfEntry : MANIFEST_VNF_METADATA) { if (!metadata.containsKey(requiredVnfEntry)) { reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredVnfEntry)); } } } - private void handlePnfMetadataEntries(Map<String, String> metadata) { - for (String requiredPnfEntry : MANIFEST_PNF_METADATA) { + private void handlePnfMetadataEntries(final Map<String, String> metadata) { + for (final String requiredPnfEntry : MANIFEST_PNF_METADATA) { if (!metadata.containsKey(requiredPnfEntry)) { reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredPnfEntry)); } @@ -295,27 +312,61 @@ class SOL004MetaDirectoryValidator implements Validator { /** * Checks if all manifest sources exists within the package and if all package files are being referred. * - * @param packageFiles The package file path list * @param onboardingManifest The manifest */ - private void verifyManifestSources(final Set<String> packageFiles, final Manifest onboardingManifest) { + private void verifyManifestSources(final Manifest onboardingManifest) { + final Set<String> packageFiles = contentHandler.getFileList(); final List<String> sources = filterSources(onboardingManifest.getSources()); verifyFilesExist(packageFiles, sources, MANIFEST_SOURCE); final Map<String, List<String>> nonManoArtifacts = onboardingManifest.getNonManoSources(); - final List<String> nonManoFiles = nonManoArtifacts.values().stream() - .map(this::filterSources) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - verifyFilesExist(packageFiles, nonManoFiles, MANIFEST_NON_MANO_SOURCE); + + final List<String> nonManoValidFilePaths = new ArrayList<>(); + nonManoArtifacts.forEach((nonManoType, files) -> { + final List<String> internalNonManoFileList = filterSources(files); + nonManoValidFilePaths.addAll(internalNonManoFileList); + if (ONAP_PM_DICTIONARY.getType().equals(nonManoType) || ONAP_VES_EVENTS.getType().equals(nonManoType)) { + internalNonManoFileList.forEach(this::validateYaml); + } + }); + + verifyFilesExist(packageFiles, nonManoValidFilePaths, MANIFEST_NON_MANO_SOURCE); final Set<String> allReferredFiles = new HashSet<>(); allReferredFiles.addAll(sources); - allReferredFiles.addAll(nonManoFiles); + allReferredFiles.addAll(nonManoValidFilePaths); verifyFilesBeingReferred(allReferredFiles, packageFiles); } /** + * Validates if a YAML file has the correct extension, is not empty and the content is a valid YAML. + * Reports each error found. + * + * @param filePath the file path inside the package + */ + private void validateYaml(final String filePath) { + if (!contentHandler.containsFile(filePath)) { + return; + } + final String fileExtension = getFileExtension(filePath); + if (!"yaml".equalsIgnoreCase(fileExtension) && !"yml".equalsIgnoreCase(fileExtension)) { + reportError(ErrorLevel.ERROR, Messages.INVALID_YAML_EXTENSION.formatMessage(filePath)); + return; + } + + final InputStream fileContent = contentHandler.getFileContent(filePath); + if (fileContent == null) { + reportError(ErrorLevel.ERROR, Messages.EMPTY_YAML_FILE_1.formatMessage(filePath)); + return; + } + try { + new Yaml().loadAll(fileContent).iterator().next(); + } catch (final Exception e) { + reportError(ErrorLevel.ERROR, Messages.INVALID_YAML_FORMAT_1.formatMessage(filePath, e.getMessage())); + } + } + + /** * Checks if all package files are referred in manifest. * Reports missing references. * @@ -330,36 +381,35 @@ class SOL004MetaDirectoryValidator implements Validator { }); } - private List<String> filterSources(List<String> source){ + private List<String> filterSources(final List<String> source){ return source.stream() .filter(this::externalFileReferences) .collect(Collectors.toList()); } - private boolean externalFileReferences(String filePath){ + private boolean externalFileReferences(final String filePath){ return !filePath.contains("://"); } - private void validateOtherEntries(List<String> folderList, String folderPath){ + private void validateOtherEntries(final 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){ + private boolean verifyFoldersExist(final List<String> folderList, final String folderPath) { return folderList.contains(folderPath + "/"); } - private void verifyFilesExist(Set<String> existingFiles, List<String> sources, String type){ - for(String file: sources){ - if(!verifyFileExists(existingFiles, file)){ + private void verifyFilesExist(final Set<String> existingFiles, final List<String> sources, final String type) { + sources.forEach(file -> { + if(!existingFiles.contains(file)){ reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_MANIFEST_SOURCE.getErrorMessage(), type, file)); } - - } + }); } - private void validateChangeLog(FileContentHandler contentHandler, String filePath){ + private void validateChangeLog(final String filePath) { if(!verifyFileExists(contentHandler.getFileList(), filePath)){ reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_METADATA_FILES.getErrorMessage(), filePath)); } @@ -369,12 +419,11 @@ class SOL004MetaDirectoryValidator implements Validator { errorsByFile.add(new ErrorMessage(errorLevel, errorMessage)); } - private Map<String, List<ErrorMessage>> getAnyValidationErrors(){ - - if(errorsByFile.isEmpty()){ + private Map<String, List<ErrorMessage>> getAnyValidationErrors() { + if (errorsByFile.isEmpty()) { return Collections.emptyMap(); } - Map<String, List<ErrorMessage>> errors = new HashMap<>(); + final 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/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java index 72f235e287..e022e2fedb 100644 --- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/impl/orchestration/csar/validation/ManifestBuilderTest.java @@ -24,6 +24,8 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_PM_DICTIONARY; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_VES_EVENTS; import java.io.ByteArrayInputStream; import java.util.Arrays; @@ -109,8 +111,8 @@ public class ManifestBuilderTest { mockManifestSource(); final Map<String, List<String>> expectedNonManoArtifactMap = new TreeMap<>(); - expectedNonManoArtifactMap.put("onap_ves_events", Arrays.asList("Files/Events/MyPnf_Pnf_v1.yaml")); - expectedNonManoArtifactMap.put("onap_pm_dictionary", Arrays.asList("Files/Measurements/PM_Dictionary.yaml")); + expectedNonManoArtifactMap.put(ONAP_VES_EVENTS.getType(), Arrays.asList("Files/Events/MyPnf_Pnf_v1.yaml")); + expectedNonManoArtifactMap.put(ONAP_PM_DICTIONARY.getType(), Arrays.asList("Files/Measurements/PM_Dictionary.yaml")); expectedNonManoArtifactMap.put("onap_yang_modules", Arrays.asList("Files/Yang_module/mynetconf.yang", "Files/Yang_module/mynetconf2.yang")); expectedNonManoArtifactMap 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 index 6a56db6e34..328f00ca90 100644 --- 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 @@ -38,6 +38,7 @@ import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -60,6 +61,8 @@ import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_PROVIDER_ID; import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_PACKAGE_VERSION; import static org.openecomp.sdc.tosca.csar.CSARConstants.VNF_RELEASE_DATE_TIME; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_PM_DICTIONARY; +import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.NonManoArtifactType.ONAP_VES_EVENTS; import static org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.TestConstants.*; public class SOL004MetaDirectoryValidatorTest { @@ -130,7 +133,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, folderList); - assertTrue(errors.size() == 0); + assertEquals(0, errors.size()); } @Test @@ -141,7 +144,7 @@ public class SOL004MetaDirectoryValidatorTest { final 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); + assertSame(ErrorLevel.ERROR, errorMessages.get(0).getLevel()); } /** @@ -209,7 +212,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertTrue(errors.size() == 0); + assertEquals(0, errors.size()); } @Test @@ -241,7 +244,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertTrue(errors.size() == 0); + assertEquals(0, errors.size()); } @Test @@ -345,14 +348,14 @@ public class SOL004MetaDirectoryValidatorTest { manifestBuilder.withSource(SAMPLE_DEFINITION_IMPORT_FILE_PATH); final String nonManoSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; - handler.addFile(nonManoSource, "".getBytes()); - manifestBuilder.withNonManoArtifact("onap_pm_events", nonManoSource); + handler.addFile(nonManoSource, getResourceBytes("/validation.files/measurements/pmEvents-valid.yaml")); + manifestBuilder.withNonManoArtifact(ONAP_PM_DICTIONARY.getType(), nonManoSource); manifestBuilder.withSource(TOSCA_MANIFEST_FILEPATH); handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertTrue(errors.size() == 0); + assertEquals(0, errors.size()); } /** @@ -377,8 +380,8 @@ public class SOL004MetaDirectoryValidatorTest { manifestBuilder.withSource(SAMPLE_DEFINITION_IMPORT_FILE_PATH); String nonManoSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; - handler.addFile(nonManoSource, "".getBytes()); - manifestBuilder.withNonManoArtifact("onap_pm_events", nonManoSource); + handler.addFile(nonManoSource, getResourceBytes("/validation.files/measurements/pmEvents-valid.yaml")); + manifestBuilder.withNonManoArtifact(ONAP_PM_DICTIONARY.getType(), nonManoSource); manifestBuilder.withSource(TOSCA_MANIFEST_FILEPATH); handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); @@ -422,7 +425,7 @@ public class SOL004MetaDirectoryValidatorTest { handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); final Map<String, List<ErrorMessage>> errors = sol004MetaDirectoryValidator.validateContent(handler, Collections.emptyList()); - assertTrue(errors.size() == 0); + assertEquals(0, errors.size()); } /** @@ -687,7 +690,7 @@ public class SOL004MetaDirectoryValidatorTest { * Tests an imported descriptor with a missing imported file. */ @Test - public void testGivenDefinitionFileWithImportedDescriptor_whenImportedDescriptorImportsMissingFile_thenMissingImportErrorOccur() throws IOException { + public void testGivenDefinitionFileWithImportedDescriptor_whenImportedDescriptorImportsMissingFile_thenMissingImportErrorOccur() { final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); @@ -757,6 +760,150 @@ public class SOL004MetaDirectoryValidatorTest { assertExpectedErrors(actualErrorMap.get(SdcCommon.UPLOAD_FILE), expectedErrorList); } + @Test + public void givenManifestWithNonManoPmAndVesArtifacts_whenNonManoArtifactsAreValid_thenNoErrorsOccur() { + final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); + + handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); + + handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); + manifestBuilder.withSource(TOSCA_DEFINITION_FILEPATH); + + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_CHANGELOG_FILEPATH); + + final String nonManoPmEventsSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; + handler.addFile(nonManoPmEventsSource, getResourceBytes("/validation.files/measurements/pmEvents-valid.yaml")); + manifestBuilder.withNonManoArtifact(ONAP_PM_DICTIONARY.getType(), nonManoPmEventsSource); + + final String nonManoVesEventsSource = "Artifacts/Deployment/Events/ves_events.yaml"; + handler.addFile(nonManoVesEventsSource, getResourceBytes("/validation.files/events/vesEvents-valid.yaml")); + manifestBuilder.withNonManoArtifact(ONAP_VES_EVENTS.getType(), nonManoVesEventsSource); + + manifestBuilder.withSource(TOSCA_MANIFEST_FILEPATH); + handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); + + final Map<String, List<ErrorMessage>> actualErrorMap = sol004MetaDirectoryValidator + .validateContent(handler, Collections.emptyList()); + + assertExpectedErrors(actualErrorMap.get(SdcCommon.UPLOAD_FILE), Collections.emptyList()); + } + + @Test + public void givenManifestWithNonManoPmOrVesArtifacts_whenNonManoArtifactsYamlAreInvalid_thenInvalidYamlErrorOccur() { + final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); + + handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); + + handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); + manifestBuilder.withSource(TOSCA_DEFINITION_FILEPATH); + + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_CHANGELOG_FILEPATH); + + final String nonManoPmEventsSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; + handler.addFile(nonManoPmEventsSource, getResourceBytes(INVALID_YAML_FILE_PATH)); + manifestBuilder.withNonManoArtifact(ONAP_PM_DICTIONARY.getType(), nonManoPmEventsSource); + + manifestBuilder.withSource(TOSCA_MANIFEST_FILEPATH); + handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); + + final List<ErrorMessage> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(new ErrorMessage(ErrorLevel.ERROR + , Messages.INVALID_YAML_FORMAT_1.formatMessage(nonManoPmEventsSource, "while scanning a simple key\n" + + " in 'reader', line 2, column 1:\n" + + " key {}\n" + + " ^\n" + + "could not find expected ':'\n" + + " in 'reader', line 2, column 7:\n" + + " {}\n" + + " ^\n")) + ); + + final Map<String, List<ErrorMessage>> actualErrorMap = sol004MetaDirectoryValidator + .validateContent(handler, Collections.emptyList()); + + assertExpectedErrors(actualErrorMap.get(SdcCommon.UPLOAD_FILE), expectedErrorList); + } + + @Test + public void givenManifestWithNonManoPmOrVesArtifacts_whenNonManoArtifactsYamlAreEmpty_thenEmptyYamlErrorOccur() { + final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); + + handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); + + handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); + manifestBuilder.withSource(TOSCA_DEFINITION_FILEPATH); + + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_CHANGELOG_FILEPATH); + + final String nonManoPmEventsSource = "Artifacts/Deployment/Measurements/PM_Dictionary.yaml"; + handler.addFile(nonManoPmEventsSource, getResourceBytes(EMPTY_YAML_FILE_PATH)); + manifestBuilder.withNonManoArtifact(ONAP_PM_DICTIONARY.getType(), nonManoPmEventsSource); + + final String nonManoVesEventsSource = "Artifacts/Deployment/Events/ves_events.yaml"; + handler.addFile(nonManoVesEventsSource, getResourceBytes(EMPTY_YAML_FILE_PATH)); + manifestBuilder.withNonManoArtifact(ONAP_VES_EVENTS.getType(), nonManoVesEventsSource); + + manifestBuilder.withSource(TOSCA_MANIFEST_FILEPATH); + handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); + + final List<ErrorMessage> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(new ErrorMessage(ErrorLevel.ERROR + , Messages.EMPTY_YAML_FILE_1.formatMessage(nonManoPmEventsSource)) + ); + expectedErrorList.add(new ErrorMessage(ErrorLevel.ERROR + , Messages.EMPTY_YAML_FILE_1.formatMessage(nonManoVesEventsSource)) + ); + + final Map<String, List<ErrorMessage>> actualErrorMap = sol004MetaDirectoryValidator + .validateContent(handler, Collections.emptyList()); + + assertExpectedErrors(actualErrorMap.get(SdcCommon.UPLOAD_FILE), expectedErrorList); + } + + @Test + public void givenManifestWithNonManoPmOrVesArtifacts_whenNonManoArtifactsHaveNotYamlExtension_thenInvalidYamlExtensionErrorOccur() { + final ManifestBuilder manifestBuilder = getVnfManifestSampleBuilder(); + + handler.addFile(TOSCA_META_PATH_FILE_NAME, metaFile.getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_META_PATH_FILE_NAME); + + handler.addFile(TOSCA_DEFINITION_FILEPATH, getResourceBytes(SAMPLE_DEFINITION_FILE_PATH)); + manifestBuilder.withSource(TOSCA_DEFINITION_FILEPATH); + + handler.addFile(TOSCA_CHANGELOG_FILEPATH, "".getBytes(StandardCharsets.UTF_8)); + manifestBuilder.withSource(TOSCA_CHANGELOG_FILEPATH); + + final String nonManoPmEventsSource = "Artifacts/Deployment/Measurements/PM_Dictionary.y1"; + handler.addFile(nonManoPmEventsSource, "".getBytes()); + manifestBuilder.withNonManoArtifact(ONAP_PM_DICTIONARY.getType(), nonManoPmEventsSource); + + final String nonManoVesEventsSource = "Artifacts/Deployment/Events/ves_events.y2"; + handler.addFile(nonManoVesEventsSource, "".getBytes()); + manifestBuilder.withNonManoArtifact(ONAP_VES_EVENTS.getType(), nonManoVesEventsSource); + + manifestBuilder.withSource(TOSCA_MANIFEST_FILEPATH); + handler.addFile(TOSCA_MANIFEST_FILEPATH, manifestBuilder.build().getBytes(StandardCharsets.UTF_8)); + + final List<ErrorMessage> expectedErrorList = new ArrayList<>(); + expectedErrorList.add(new ErrorMessage(ErrorLevel.ERROR + , Messages.INVALID_YAML_EXTENSION.formatMessage(nonManoPmEventsSource)) + ); + expectedErrorList.add(new ErrorMessage(ErrorLevel.ERROR + , Messages.INVALID_YAML_EXTENSION.formatMessage(nonManoVesEventsSource)) + ); + + final Map<String, List<ErrorMessage>> actualErrorMap = sol004MetaDirectoryValidator + .validateContent(handler, Collections.emptyList()); + + assertExpectedErrors(actualErrorMap.get(SdcCommon.UPLOAD_FILE), expectedErrorList); + } + private void assertExpectedErrors(final String testCase, final Map<String, List<ErrorMessage>> errors, final int expectedErrors){ final List<ErrorMessage> errorMessages = errors.get(SdcCommon.UPLOAD_FILE); printErrorMessages(errorMessages); @@ -769,9 +916,9 @@ public class SOL004MetaDirectoryValidatorTest { private void printErrorMessages(final List<ErrorMessage> errorMessages) { if (CollectionUtils.isNotEmpty(errorMessages)) { - errorMessages.forEach(errorMessage -> { - System.out.println(String.format("%s: %s", errorMessage.getLevel(), errorMessage.getMessage())); - }); + errorMessages.forEach(errorMessage -> + System.out.println(String.format("%s: %s", errorMessage.getLevel(), errorMessage.getMessage())) + ); } } @@ -808,6 +955,8 @@ public class SOL004MetaDirectoryValidatorTest { actualErrorList = new ArrayList<>(); } + printErrorMessages(actualErrorList); + assertThat("The actual error list should have the same size as the expected error list" , actualErrorList, hasSize(expectedErrorList.size()) ); 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 index 57619646c9..42022fc90b 100644 --- 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 @@ -30,6 +30,8 @@ class TestConstants { 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 EMPTY_YAML_FILE_PATH = "/validation.files/empty.yaml"; + public static final String INVALID_YAML_FILE_PATH = "/validation.files/invalid.yaml"; private TestConstants(){ diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/empty.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/empty.yaml new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/empty.yaml diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/events/vesEvents-valid.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/events/vesEvents-valid.yaml new file mode 100644 index 0000000000..83f1d3e8e5 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/events/vesEvents-valid.yaml @@ -0,0 +1,213 @@ +--- +event: + presence: required + structure: + commonEventHeader: + presence: required + structure: + domain: {presence: required, value: notification} + eventName: {presence: required, value: Noti_MyPnf-Acme_FileReady} + priority: {presence: required, value: Normal} + eventId: {presence: required} + reportingEntityId: {presence: required} + reportingEntityName: {presence: required} + sequence: {presence: required, value: 0} + sourceId: {presence: required} + sourceName: {presence: required} + version: {presence: required, value: 4.0.1} + vesEventListenerVersion: {presence: required, value: 7.0.1} + startEpochMicrosec: {presence: required} + lastEpochMicrosec: {presence: required} + notificationFields: + presence: required + structure: + changeIdentifier: {presence: required, value: PM_MEAS_FILES} + changeType: {presence: required, value: fileReady} + notificationFieldsVersion: {presence: required, value: 2.0} + arrayOfNamedHashMap: + presence: required + array: + - name: {presence: required} + hashMap: {presence: required, structure: { + keyValuePair: {presence: required, structure: {key: {presence: required, value: location}, value: {presence: required}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: compression}, value: {presence: required, value: gzip}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: fileFormatType}, value: {presence: required, value: org.3GPP.32.435}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: fileFormatVersion}, value: {presence: required, value: V10}}}} + } +... +--- +event: + presence: required + structure: + commonEventHeader: + presence: required + structure: + domain: {presence: required, value: pnfRegistration} + eventId: {presence: required} + eventName: {presence: required, value: PnfReg_MyPnf-Acme_pnfRegistration} + lastEpochMicrosec: {presence: required} + priority: {presence: required, value: Normal} + reportingEntityName: {presence: required} + sequence: {presence: required, value: 0} + sourceName: {presence: required} + startEpochMicrosec: {presence: required} + timeZoneOffset: {presence: required} + version: {presence: required, value: 4.0.1} + vesEventListenerVersion: {presence: required, value: 7.0.1} + pnfRegistrationFields: + presence: required + structure: + modelNumber: {presence: required} + oamV4IpAddress: {presence: optional} + oamV6IpAddress: {presence: optional} + pnfRegistrationFieldsVersion: {presence: required, value: 2.0} + serialNumber: {presence: required} + softwareVersion: {presence: required} + unitFamily: {presence: required, value: BBU} + unitType: {presence: required} + vendorName: {presence: required, value: Acme} +... +--- +event: + presence: required + action: [ any, any, null, null, null ] + comment: " + ALARM NAME: CertMAutomaticEnrollmentFailed, + ALARM DESCRIPTION: ‘See alarm OPI x/1111-ABC 123 4567/1 Uen’, + ALARM EFFECT: 'See alarm OPI x/2222-ABC 123 4567/1 Uen', + MANAGED OBJECT CLASSES: NodeCredential, + EVENT TYPE: 'PROCESSINGERRORALARM', + PROBABLE CAUSE: 'ConfigurationOrCustomizationError', + PROPOSED REPAIR ACTIONS: 'See alarm OPI x/3333-ABC 123 4567/1 Uen', + CLEARING TYPE: Automatic + " + structure: + commonEventHeader: + presence: required + structure: + version: {presence: required, value: 4.0.1} + vesEventListenerVersion: {presence: required, value: 7.0.1} + domain: {presence: required, value: fault} + eventName: {presence: required, value: Fault_MyPnf-Acme_CertMAutomaticEnrollmentFailed} + eventId: {presence: required} + sequence: {presence: required} + priority: {presence: required, value: Normal} + reportingEntityName: {presence: required} + sourceName: {presence: required} + nfVendorName: {presence: required, value: Acme} + startEpochMicrosec: {presence: required} + lastEpochMicrosec: {presence: required} + timeZoneOffset: {presence: required} + faultFields: + presence: required + structure: + faultFieldsVersion: {presence: required, value: 4.0} + alarmCondition: {presence: required, value: 'CertMAutomaticEnrollmentFailed'} + eventCategory: {presence: required, value: 'PROCESSINGERRORALARM'} + eventSourceType: {presence: required} + specificProblem: {presence: required, value: 'Certificate Management Automatic Enrollment Failed'} + eventSeverity: {presence: required} + vfStatus: {presence: required, value: Active} + alarmAdditionalInformation: {presence: required, structure: { + keyValuePair: {presence: required, structure: {key: {presence: required, value: source}, value: {presence: required}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: probableCause}, value: {presence: required, value: 'ConfigurationOrCustomizationError'}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalText}, value: {presence: optional}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalInfo}, value: {presence: optional}}}} + } +... +--- +event: + presence: required + action: [ any, any, null, null, null ] + comment: " + ALARM NAME: PowerLoss, + ALARM DESCRIPTION: 'PNF is losing power', + ALARM EFFECT: 'PNF will shutdown if battery is drained', + MANAGED OBJECT CLASSES: 'BatteryBackup;BatteryUnit', + EVENT TYPE: 'EQUIPMENTALARM', + PROBABLE CAUSE: 'Power Supply Failure', + PROPOSED REPAIR ACTIONS: 'Repair Power Supply', + CLEARING TYPE: Automatic + " + structure: + commonEventHeader: + presence: required + structure: + version: {presence: required, value: 4.0.1} + vesEventListenerVersion: {presence: required, value: 7.0.1} + domain: {presence: required, value: fault} + eventName: {presence: required, value: Fault_MyPnf-Acme_PowerLoss} + eventId: {presence: required} + sequence: {presence: required} + priority: {presence: required, value: Normal} + reportingEntityName: {presence: required} + sourceName: {presence: required} + nfVendorName: {presence: required, value: Acme} + startEpochMicrosec: {presence: required} + lastEpochMicrosec: {presence: required} + timeZoneOffset: {presence: required} + faultFields: + presence: required + structure: + faultFieldsVersion: {presence: required, value: 4.0} + alarmCondition: {presence: required, value: 'PowerLoss'} + eventCategory: {presence: required, value: 'EQUIPMENTALARM'} + eventSourceType: {presence: required} + specificProblem: {presence: required, value: 'Power Supply Failure'} + eventSeverity: {presence: required} + vfStatus: {presence: required, value: Active} + alarmAdditionalInformation: {presence: required, structure: { + keyValuePair: {presence: required, structure: {key: {presence: required, value: source}, value: {presence: required}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: probableCause}, value: {presence: required, value: 'Power Supply Failure'}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalText}, value: {presence: optional}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalInfo}, value: {presence: optional}}}} + } +... +--- +event: + presence: required + action: [ any, any, null, null, null ] + comment: " + ALARM NAME: LogHasReachedFullCapacity, + ALARM DESCRIPTION: 'Log Has Reached Full Capacity', + ALARM EFFECT: 'See alarm OPI x/2223-ABC 123 4567/1 Uen', + MANAGED OBJECT CLASSES: Log, + EVENT TYPE: 'PROCESSINGERRORALARM', + PROBABLE CAUSE: 'FileError', + PROPOSED REPAIR ACTIONS: 'See alarm OPI x/3334-ABC 123 4567/1 Uen', + CLEARING TYPE: Automatic + " + structure: + commonEventHeader: + presence: required + structure: + version: {presence: required, value: 4.0.1} + vesEventListenerVersion: {presence: required, value: 7.0.1} + domain: {presence: required, value: fault} + eventName: {presence: required, value: Fault_MyPnf-Acme_LogHasReachedFullCapacity} + eventId: {presence: required} + sequence: {presence: required} + priority: {presence: required, value: Normal} + reportingEntityName: {presence: required} + sourceName: {presence: required} + nfVendorName: {presence: required, value: Acme} + startEpochMicrosec: {presence: required} + lastEpochMicrosec: {presence: required} + timeZoneOffset: {presence: required} + faultFields: + presence: required + structure: + faultFieldsVersion: {presence: required, value: 4.0} + alarmCondition: {presence: required, value: 'LogHasReachedFullCapacity'} + eventCategory: {presence: required, value: 'PROCESSINGERRORALARM'} + eventSourceType: {presence: required} + specificProblem: {presence: required, value: 'Log Has Reached Full Capacity'} + eventSeverity: {presence: required} + vfStatus: {presence: required, value: Active} + alarmAdditionalInformation: {presence: required, structure: { + keyValuePair: {presence: required, structure: {key: {presence: required, value: source},value: {presence: required}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: probableCause},value: {presence: required, value: 'FileError'}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalText},value: {presence: optional}}}, + keyValuePair: {presence: required, structure: {key: {presence: required, value: additionalInfo},value: {presence: optional}}}} + } +...
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/invalid.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/invalid.yaml new file mode 100644 index 0000000000..7df3b2b083 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/invalid.yaml @@ -0,0 +1,2 @@ +key: 1 +key {}
\ No newline at end of file diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/measurements/pmEvents-valid.yaml b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/measurements/pmEvents-valid.yaml new file mode 100644 index 0000000000..858951f7b0 --- /dev/null +++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/test/resources/validation.files/measurements/pmEvents-valid.yaml @@ -0,0 +1,186 @@ +pmDictionary: + presence: required + structure: + pmDictionaryHeader: + presence: required + structure: + pmDefVsn: { presence: required, comment: "Version of the PM Dictionary. Version is vendor defined."} + pmDefSchemaVsn: { presence: required, comment: "Version of the PM Dictionary Schema used for this PM Dictionary. Schema versions are specified in the VES Specifications."} + nfType: { presence: required, comment: "NF type to whom this PM Dictionary applies. nfType is vendor defined and should match the string used in eventName."} + vendor: { presence: required, value: Acme, comment: "Vendor of the NF type to whom this PM Dictionary applies."} + pmDictionaryMeasurements: + presence: required + array: + - measType: { presence: required, comment: "Measurement name used in PM file, in 3GPP format where specified, else vendor defined. Names for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item e). Names for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item e). Vendor defined names are preceded with VS."} + measDescription: { presence: required, comment: "Text description of the purpose of the measurement, what information does the measurement provide. Descriptions for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item a). Descriptions for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item a). Vendors are free to augment or modify the 3GPP-provided descriptions to more accurately describe their measurements as needed."} + measCondition: { presence: required, comment: "Text description of the condition that causes the measurement to be updated. Conditions for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item c). Conditions for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item c). Vendors are free to augment or modify the 3GPP-provided conditions to more accurately describe their measurements as needed."} + measResultType: { presence: required, value: [integer], comment: "Data type of the measurement result. Result data types for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item d). Result data types for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item d). The measResultType values supported by a vendor are specified in the PM Dictionary YAML using the 'value' attribute and may include vendor-defined data types not specified by 3GPP; for example boolean."} + measResultRange: { presence: optional, comment: "Range for the measurement result. The range is specified as a comma separated list of discrete values or a range of values specified as minimum value-maximum value with no spaces. Result ranges for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item d) if applicable. Result ranges for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item d) if applicable. "} + measResultUnits: { presence: required, value: [seconds, minutes, nanoseconds, microseconds, kbps], comment: "Unit of measure for the result; e.g. milliseconds, bytes, kilobytes, packets, number. Unit of measure for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item d) if applicable. Unit of measure for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item d) if applicable. The measResultsUnits values supported by a vendor are specified in the PM Dictionary YAML using the 'value' attribute and may include vendor-defined units of measure not specified by 3GPP; for example ethernet frames."} + measObjClass: { presence: required, value: [NRCellCU, NRCellDU, NRBTS, IPNO, ETHIF], comment: "Measurement Object Class. Object classes for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item f). Object classes for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item f). The measObjClass values supported by a vendor are specified in the PM Dictionary YAML using the “value” attribute and may include vendor-defined objects not specified by 3GPP; for example IPSEC."} + measCollectionMethod: { presence: required, value: [CC, GUAGE, DER, SI], comment: "Collection Method for the measurement. 3GPP-defined collection methods are CC, SI, DER and Gauge. Collection Methods for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 item b). Collection Methods for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 item c). The measCollectionMethod values supported by a vendor are specified in the PM Dictionary YAML using the 'value' attribute and may include vendor-defined collection methods not specified by 3GPP; for example Average."} + measLastChange: { presence: required, comment: "PM Dictionary version the last time this measurement was changed, added or deleted."} + measChangeType: { presence: required, value: [added, modified, deleted], comment: "For the measLastChange, indicates the type of change made for this measurement. Valid values are added, modified or deleted. Deleted measurements may be kept in the PM Dictionary for one release or more or permanently for historical purposes, if desired."} + measInfoId: { presence: required, comment: "Name for a group of related measurements, in 3GPP format where specified, else vendor defined. Family names for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 Section 3.1. Family names for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 Section 3.4."} + measFamily: { presence: required, comment: "Abbreviation for a family of measurements, in 3GPP format where specified, else vendor defined. Family name abbreviations for 3GPP-defined 4G measurements are specified in 3GPP TS 32.425 Section 3.1. Family name abbreviations for 3GPP-defined 5G measurements are specified in 3GPP TS 28.552 Section 3.4. "} + measAdditionalFields: { presence: required, comment: "Hashmap of vendor specific PM Dictionary fields in key value pair format.", structure: { + keyValuePair: { presence: required, structure: { key: { presence: required, value: measurementStatus, comment: "Contains the status of the measurement."}, value: { presence: required, value: [USED, DEPRECATED, OBSOLETE, PRELIMINARY] }}}, + keyValuePair: { presence: required, structure: { key: { presence: required, value: initialValue, comment: "The initial value to which the Measurement Type is set at the beginning of a new granularity period."}, value: { presence: required }}}, + keyValuePair: { presence: required, structure: { key: { presence: required, value: acmeParameter1, comment: "Extra vendor specific parameter 1."}, value: { presence: required }}}, + keyValuePair: { presence: optional, structure: { key: { presence: required, value: acmeParameter2, comment: "Extra vendor specific parameter 2."}, value: { presence: required, value: [true, false] }}}, + keyValuePair: { presence: optional, structure: { key: { presence: required, value: acmeParameter3, comment: "Extra vendor specific parameter 3."}, value: { presence: required }}}} + } +--- +pmDictionary: + pmDictionaryHeader: + pmDefVsn: AcmeNumber.1.0 + pmDefSchemaVsn: 1.0 + nfType: myPnf + vendor: Acme + pmDictionaryMeasurements: + + - measType: DRB.UEThpDl + measDescription: Average DL UE throughput in gNB + measCondition: See 3GPP TS 28.552 + measResultType: integer + measResultRange: 0-4294967295 + measResultUnits: kbps + measObjClass: NRCellDU + measCollectionMethod: DER + measLastChange: 1.0 + measChangeType: added + measInfoId: "Data Radio Bearer" + measFamily: DRB + measAdditionalFields: { + "measurementStatus": "USED", + "initialValue": 0, + "acmeParameter1": 0, + "acmeParameter2": true, + "acmeParameter3": "acmeParameterValue3"} + + - measType: VS.ifInDiscards + measDescription: The number of inbound packets which were chosen to be discarded + measCondition: The number of inbound packets which were chosen to be + discarded even though no errors had been detected to prevent + their being deliverable to a higher-layer protocol. One + possible reason for discarding such a packet could be to + free up buffer space. + Discontinuities in the value of this counter can occur at + re-initialization of the management system, and at other + times as indicated by the value of + ifCounterDiscontinuityTime. + measResultType: integer + measResultRange: 0-4294967295 + measResultUnits: number + measObjClass: EthernetPort + measCollectionMethod: CC + measLastChange: 1.0 + measChangeType: added + measInfoId: "IP Management" + measFamily: IP + measAdditionalFields: { + "measurementStatus": "USED", + "initialValue": 0, + "acmeParameter1": 0, + "acmeParameter2": true, + "acmeParameter3": "acmeParameterValue3"} + + - measType: VS.ifInErrors + measDescription: Number of inbound packets that contained errors + measCondition: For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of inbound + transmission units that contained errors preventing them + from being deliverable to a higher-layer protocol. + measResultType: integer + measResultRange: 0-4294967295 + measResultUnits: number + measObjClass: EthernetPort + measCollectionMethod: Gauge + measLastChange: 1.0 + measChangeType: added + measInfoId: "IP Management" + measFamily: IP + measAdditionalFields: { + "measurementStatus": "USED", + "initialValue": 0, + "acmeParameter1": 0, + "acmeParameter3": "acmeParameterValue3"} + + - measType: VS.ifInUnknownProtos + measDescription: Number of inbound packets received via an unknown or usupported protocol + measCondition: For packet-oriented interfaces, the number of packets + received via the interface which were discarded because of + an unknown or unsupported protocol. For character-oriented + or fixed-length interfaces that support protocol + multiplexing the number of transmission units received via + the interface which were discarded because of an unknown or + unsupported protocol. For any interface that does not + support protocol multiplexing, this counter will always be + 0. + measResultType: integer + measResultRange: 0-4294967295 + measResultUnits: number + measObjClass: EthernetPort + measCollectionMethod: CC + measLastChange: 1.0 + measChangeType: added + measInfoId: "IP Management" + measFamily: IP + measAdditionalFields: { + "measurementStatus": "USED", + "initialValue": 0, + "acmeParameter1": 0, + "acmeParameter2": true} + + - measType: VS.ifHCInBroadcastPkts + measDescription: Number of the broadcasted inbound packets delivered to the higher (sub-)layer + measCondition: The number of packets, delivered by this sub-layer to a + higher (sub-)layer, which were addressed to a broadcast + address at this sub-layer. This object is a 64-bit version + of ifInBroadcastPkts. + Discontinuities in the value of this counter can occur at + re-initialization of the management system, and at other + times as indicated by the value of + ifCounterDiscontinuityTime. + measResultType: integer + measResultRange: 0-4294967295 + measResultUnits: number + measObjClass: EthernetPort + measCollectionMethod: CC + measLastChange: 1.0 + measChangeType: added + measInfoId: "IP Management" + measFamily: IP + measAdditionalFields: { + "measurementStatus": "USED", + "initialValue": 0, + "acmeParameter1": 0} + + - measType: VS.ifHCOutBroadcastPkts + measDescription: Number of the broadcasted outsbound packets delivered to the higher (sub-)layer + measCondition: The total number of packets that higher-level protocols + requested be transmitted, and which were addressed to a + broadcast address at this sub-layer, including those that + were discarded or not sent. This object is a 64-bit version + of ifOutBroadcastPkts. + Discontinuities in the value of this counter can occur at + re-initialization of the management system, and at other + times as indicated by the value of + ifCounterDiscontinuityTime. + measResultType: integer + measResultRange: 0-4294967295 + measResultUnits: number + measObjClass: EthernetPort + measCollectionMethod: CC + measLastChange: 1.0 + measChangeType: added + measInfoId: "IP Management" + measFamily: IP + measAdditionalFields: { + "measurementStatus": "USED", + "initialValue": 0, + "acmeParameter1": 0, + "acmeParameter2": true, + "acmeParameter3": "acmeParameterValue3"} 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 12359fdb14..7d2f8b2a36 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 @@ -111,11 +111,15 @@ public enum Messages { MISSING_DEFINITION_FILE("Definition file %s referenced in TOSCA.meta does not exist"), MISSING_IMPORT_FILE("Package must contain the referenced import file '%s'"), INVALID_IMPORT_STATEMENT("Definition file '%s' contains an invalid import statement: '%s'"), + INVALID_YAML_EXTENSION("Expecting yaml or yml extension for file: %s"), + /* content errors*/ - INVALID_YAML_FORMAT("Invalid YAML format - %s"), + INVALID_YAML_FORMAT("Invalid YAML format: %s"), + INVALID_YAML_FORMAT_1("Invalid YAML format in file '%s'. Format error:%n%s"), INVALID_YAML_FORMAT_REASON("Invalid YAML format Problem - [%s]"), EMPTY_YAML_FILE("empty yaml"), + EMPTY_YAML_FILE_1("The yaml file '%s' is empty"), GENERAL_YAML_PARSER_ERROR("general parser error"), GENERAL_HEAT_PARSER_ERROR("general parser error"), INVALID_HEAT_FORMAT_REASON("Invalid HEAT format problem - [%s]"), diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/pom.xml b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/pom.xml index 02be9a6adc..213d6e1f44 100644 --- a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/pom.xml +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/pom.xml @@ -25,14 +25,20 @@ <version>${project.version}</version> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> - <version>${hamcrest-all.version}</version> + <version>${hamcrest.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> @@ -116,6 +116,7 @@ Modifications copyright (c) 2018-2019 Nokia <extentreports.version>3.0.3</extentreports.version> <cucumber.version>2.4.0</cucumber.version> <bean-matchers.version>0.11</bean-matchers.version> + <hamcrest.version>2.1</hamcrest.version> <hamcrest-all.version>1.3</hamcrest-all.version> <junit-jupiter.version>5.4.0</junit-jupiter.version> <junit-vintage.version>5.4.0</junit-vintage.version> |