2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
19 * * Modifications copyright (c) 2020 Nokia
20 * ================================================================================
22 package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation;
24 import static org.openecomp.sdc.be.config.NonManoArtifactType.ONAP_CNF_HELM;
25 import static org.openecomp.sdc.be.config.NonManoArtifactType.ONAP_PM_DICTIONARY;
26 import static org.openecomp.sdc.be.config.NonManoArtifactType.ONAP_SW_INFORMATION;
27 import static org.openecomp.sdc.be.config.NonManoArtifactType.ONAP_VES_EVENTS;
28 import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_0;
29 import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_1;
30 import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_METADATA_LIMIT;
31 import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_PNF_METADATA;
32 import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_VNF_METADATA;
33 import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_MANIFEST_FILE_EXT;
34 import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_TYPE_PNF;
35 import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_TYPE_VNF;
36 import static org.openecomp.sdc.tosca.csar.ToscaMetaEntry.CREATED_BY_ENTRY;
37 import static org.openecomp.sdc.tosca.csar.ToscaMetaEntry.CSAR_VERSION_ENTRY;
38 import static org.openecomp.sdc.tosca.csar.ToscaMetaEntry.ENTRY_DEFINITIONS;
39 import static org.openecomp.sdc.tosca.csar.ToscaMetaEntry.ETSI_ENTRY_CERTIFICATE;
40 import static org.openecomp.sdc.tosca.csar.ToscaMetaEntry.ETSI_ENTRY_MANIFEST;
41 import static org.openecomp.sdc.tosca.csar.ToscaMetaEntry.TOSCA_META_FILE_VERSION_ENTRY;
42 import static org.openecomp.sdc.tosca.csar.ToscaMetadataFileInfo.TOSCA_META_FILE_VERSION_1_0;
43 import static org.openecomp.sdc.tosca.csar.ToscaMetadataFileInfo.TOSCA_META_PATH_FILE_NAME;
45 import com.google.common.collect.ImmutableSet;
46 import java.io.IOException;
47 import java.io.InputStream;
48 import java.util.ArrayList;
49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.HashSet;
52 import java.util.List;
54 import java.util.Optional;
56 import java.util.concurrent.CopyOnWriteArrayList;
57 import java.util.stream.Collectors;
58 import java.util.stream.Stream;
59 import org.apache.commons.collections.CollectionUtils;
60 import org.apache.commons.io.FilenameUtils;
61 import org.openecomp.core.impl.ToscaDefinitionImportHandler;
62 import org.openecomp.core.utilities.file.FileContentHandler;
63 import org.openecomp.sdc.be.config.NonManoArtifactType;
64 import org.openecomp.sdc.be.csar.pnf.PnfSoftwareInformation;
65 import org.openecomp.sdc.be.csar.pnf.SoftwareInformationArtifactYamlParser;
66 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
67 import org.openecomp.sdc.common.errors.Messages;
68 import org.openecomp.sdc.common.utils.SdcCommon;
69 import org.openecomp.sdc.datatypes.error.ErrorLevel;
70 import org.openecomp.sdc.datatypes.error.ErrorMessage;
71 import org.openecomp.sdc.logging.api.Logger;
72 import org.openecomp.sdc.logging.api.LoggerFactory;
73 import org.openecomp.sdc.tosca.csar.Manifest;
74 import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata;
75 import org.openecomp.sdc.tosca.csar.SOL004ManifestOnboarding;
76 import org.openecomp.sdc.tosca.csar.ToscaMetaEntry;
77 import org.openecomp.sdc.tosca.csar.ToscaMetadata;
78 import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.OnboardingPackageContentHandler;
79 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.exception.MissingCertificateException;
80 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils.FileExtractor;
81 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils.InternalFilesFilter;
82 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.utils.ValidatorUtils;
83 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.exceptions.InvalidManifestMetadataException;
84 import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManager;
85 import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException;
86 import org.yaml.snakeyaml.Yaml;
89 * 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
92 class SOL004MetaDirectoryValidator implements Validator {
94 private static final Logger LOGGER = LoggerFactory.getLogger(SOL004MetaDirectoryValidator.class);
95 private static final String MANIFEST_SOURCE = "Source";
96 private static final String MANIFEST_NON_MANO_SOURCE = "Non-MANO Source";
97 protected final ValidatorUtils validatorUtils = new ValidatorUtils();
98 private final List<ErrorMessage> errorsByFile = new CopyOnWriteArrayList<>();
99 private final SecurityManager securityManager;
100 private final InternalFilesFilter internalFilesFilter = new InternalFilesFilter();
101 private OnboardingPackageContentHandler contentHandler;
102 private Set<String> folderList;
103 private ToscaMetadata toscaMetadata;
105 public SOL004MetaDirectoryValidator() {
106 securityManager = SecurityManager.getInstance();
110 SOL004MetaDirectoryValidator(final SecurityManager securityManager) {
111 this.securityManager = securityManager;
114 private boolean packageHasCertificate() {
115 final String certificatePath = getCertificatePath().orElse(null);
116 return contentHandler.containsFile(certificatePath);
119 private Optional<String> getCertificatePath() {
120 return toscaMetadata.getEntry(ETSI_ENTRY_CERTIFICATE);
124 * Parses the {@link org.openecomp.sdc.tosca.csar.ToscaMetadataFileInfo#TOSCA_META_PATH_FILE_NAME} file
126 private void parseToscaMetadata() {
128 toscaMetadata = OnboardingToscaMetadata.parseToscaMetadataFile(contentHandler.getFileContentAsStream(TOSCA_META_PATH_FILE_NAME));
129 } catch (final IOException e) {
130 reportError(ErrorLevel.ERROR, Messages.METADATA_PARSER_INTERNAL.getErrorMessage());
131 LOGGER.error(Messages.METADATA_PARSER_INTERNAL.getErrorMessage(), e.getMessage(), e);
135 private void verifyMetadataFile() {
136 if (toscaMetadata.isValid() && hasETSIMetadata()) {
137 verifyManifestNameAndExtension();
138 handleMetadataEntries();
140 errorsByFile.addAll(toscaMetadata.getErrors());
144 private void verifySignedFiles() {
145 final Map<String, String> signedFileMap = contentHandler.getFileAndSignaturePathMap(SecurityManager.ALLOWED_SIGNATURE_EXTENSIONS);
146 final String packageCertificatePath = getCertificatePath().orElse(null);
147 final byte[] packageCert = contentHandler.getFileContent(packageCertificatePath);
148 if (packageCert == null) {
149 throw new MissingCertificateException("Expected package certificate");
151 signedFileMap.entrySet().stream().filter(entry -> entry.getValue() != null).forEach(entry -> {
152 final String filePath = entry.getKey();
153 final String fileSignaturePath = entry.getValue();
154 final byte[] fileBytes = contentHandler.getFileContent(filePath);
155 final byte[] fileSignatureBytes = contentHandler.getFileContent(fileSignaturePath);
157 if (!securityManager.verifySignedData(fileSignatureBytes, packageCert, fileBytes)) {
158 reportError(ErrorLevel.ERROR, Messages.ARTIFACT_INVALID_SIGNATURE.formatMessage(fileSignaturePath, filePath));
160 } catch (final SecurityManagerException e) {
161 final String errorMessage = Messages.ARTIFACT_SIGNATURE_VALIDATION_ERROR
162 .formatMessage(fileSignaturePath, filePath, packageCertificatePath, e.getMessage());
163 reportError(ErrorLevel.ERROR, errorMessage);
164 LOGGER.error(errorMessage, e);
169 private void verifyManifestNameAndExtension() {
170 final Map<String, String> entries = toscaMetadata.getMetaEntries();
171 final String manifestFileName = getFileName(entries.get(ETSI_ENTRY_MANIFEST.getName()));
172 final String manifestExtension = getFileExtension(entries.get(ETSI_ENTRY_MANIFEST.getName()));
173 final String mainDefinitionFileName = getFileName(entries.get(ENTRY_DEFINITIONS.getName()));
174 if (!(TOSCA_MANIFEST_FILE_EXT).equals(manifestExtension)) {
175 reportError(ErrorLevel.ERROR, Messages.MANIFEST_INVALID_EXT.getErrorMessage());
177 if (!mainDefinitionFileName.equals(manifestFileName)) {
178 reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_INVALID_NAME.getErrorMessage(), manifestFileName, mainDefinitionFileName));
182 private String getFileExtension(final String filePath) {
183 return FilenameUtils.getExtension(filePath);
186 private String getFileName(final String filePath) {
187 return FilenameUtils.getBaseName(filePath);
190 private boolean hasETSIMetadata() {
191 final Map<String, String> entries = toscaMetadata.getMetaEntries();
192 return hasEntry(entries, TOSCA_META_FILE_VERSION_ENTRY.getName()) && hasEntry(entries, CSAR_VERSION_ENTRY.getName()) && hasEntry(entries,
193 CREATED_BY_ENTRY.getName());
196 private boolean hasEntry(final Map<String, String> entries, final String mandatoryEntry) {
197 if (!entries.containsKey(mandatoryEntry)) {
198 reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_ENTRY.getErrorMessage(), mandatoryEntry));
204 private void handleMetadataEntries() {
205 toscaMetadata.getMetaEntries().entrySet().parallelStream().forEach(this::handleEntry);
208 private void handleEntry(final Map.Entry<String, String> entry) {
209 final String key = entry.getKey();
210 final ToscaMetaEntry toscaMetaEntry = ToscaMetaEntry.parse(entry.getKey()).orElse(null);
211 // allows any other unknown entry
212 if (toscaMetaEntry == null) {
215 final String value = entry.getValue();
216 switch (toscaMetaEntry) {
217 case TOSCA_META_FILE_VERSION_ENTRY:
218 case CSAR_VERSION_ENTRY:
219 case CREATED_BY_ENTRY:
220 verifyMetadataEntryVersions(key, value);
222 case ENTRY_DEFINITIONS:
223 validateDefinitionFile(value);
225 case ETSI_ENTRY_MANIFEST:
226 validateManifestFile(value);
228 case ETSI_ENTRY_CHANGE_LOG:
229 validateChangeLog(value);
231 case ETSI_ENTRY_TESTS:
232 case ETSI_ENTRY_LICENSES:
233 validateOtherEntries(entry);
235 case ETSI_ENTRY_CERTIFICATE:
236 validateCertificate(value);
239 handleOtherEntry(entry);
244 private void validateOtherEntries(final Map.Entry<String, String> entry) {
245 final String manifestFile = toscaMetadata.getMetaEntries().get(ETSI_ENTRY_MANIFEST.getName());
246 if (verifyFileExists(contentHandler.getFileList(), manifestFile)) {
247 final Manifest onboardingManifest = new SOL004ManifestOnboarding();
248 onboardingManifest.parse(contentHandler.getFileContentAsStream(manifestFile));
249 final Optional<ResourceTypeEnum> resourceType = onboardingManifest.getType();
250 if (resourceType.isPresent() && resourceType.get() == ResourceTypeEnum.VF) {
251 final String value = (String) entry.getValue();
252 validateOtherEntries(value);
254 final String key = (String) entry.getKey();
255 reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_INVALID_PNF_METADATA.getErrorMessage(), key));
260 private void verifyMetadataEntryVersions(final String key, final String version) {
261 if (!(isValidTOSCAVersion(key, version) || isValidCSARVersion(key, version) || CREATED_BY_ENTRY.getName().equals(key))) {
262 errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, String.format(Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version)));
263 LOGGER.error("{}: key {} - value {} ", Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version);
267 private boolean isValidTOSCAVersion(final String key, final String version) {
268 return TOSCA_META_FILE_VERSION_ENTRY.getName().equals(key) && TOSCA_META_FILE_VERSION_1_0.equals(version);
271 private boolean isValidCSARVersion(final String value, final String version) {
272 return CSAR_VERSION_ENTRY.getName().equals(value) && (CSAR_VERSION_1_1.equals(version) || CSAR_VERSION_1_0.equals(version));
275 protected void validateDefinitionFile(final String filePath) {
276 final Set<String> existingFiles = contentHandler.getFileList();
277 if (verifyFileExists(existingFiles, filePath)) {
278 final ToscaDefinitionImportHandler toscaDefinitionImportHandler = new ToscaDefinitionImportHandler(contentHandler.getFiles(), filePath);
279 final List<ErrorMessage> validationErrorList = toscaDefinitionImportHandler.getErrors();
280 if (CollectionUtils.isNotEmpty(validationErrorList)) {
281 errorsByFile.addAll(validationErrorList);
284 reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_DEFINITION_FILE.getErrorMessage(), filePath));
288 private boolean verifyFileExists(final Set<String> existingFiles, final String filePath) {
289 return existingFiles.contains(filePath);
292 private void validateManifestFile(final String filePath) {
293 final Set<String> existingFiles = contentHandler.getFileList();
294 if (verifyFileExists(existingFiles, filePath)) {
295 final Manifest onboardingManifest = new SOL004ManifestOnboarding();
296 onboardingManifest.parse(contentHandler.getFileContentAsStream(filePath));
297 if (onboardingManifest.isValid()) {
299 verifyManifestMetadata(onboardingManifest.getMetadata());
300 } catch (final InvalidManifestMetadataException e) {
301 reportError(ErrorLevel.ERROR, e.getMessage());
302 LOGGER.error(e.getMessage(), e);
304 verifyManifestSources(onboardingManifest);
306 final List<String> manifestErrors = onboardingManifest.getErrors();
307 manifestErrors.forEach(error -> reportError(ErrorLevel.ERROR, error));
310 reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_NOT_FOUND.getErrorMessage(), filePath));
314 private void verifyManifestMetadata(final Map<String, String> metadata) {
315 if (!validMetaLimit(metadata)) {
316 reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT.getErrorMessage(), MANIFEST_METADATA_LIMIT));
318 handleMetadataEntries(metadata);
321 protected boolean isPnfMetadata(final Map<String, String> metadata) {
322 final String firstMetadataDefinition = metadata.keySet().iterator().next();
323 final String expectedMetadataType = firstMetadataDefinition.contains(TOSCA_TYPE_PNF) ? TOSCA_TYPE_PNF : TOSCA_TYPE_VNF;
324 if (metadata.keySet().stream().anyMatch((final String metadataEntry) -> !metadataEntry.contains(expectedMetadataType))) {
325 throw new InvalidManifestMetadataException(Messages.MANIFEST_METADATA_INVALID_ENTRY.getErrorMessage());
327 return TOSCA_TYPE_PNF.equals(expectedMetadataType);
330 private void handleMetadataEntries(final Map<String, String> metadata) {
331 getManifestMetadata(metadata).stream().filter(requiredEntry -> !metadata.containsKey(requiredEntry)).forEach(
332 requiredEntry -> reportError(ErrorLevel.ERROR, String.format(Messages.MANIFEST_METADATA_MISSING_ENTRY.getErrorMessage(), requiredEntry)));
336 * Checks if all manifest sources exists within the package and if all package files are being referred.
338 * @param onboardingManifest The manifest
340 private void verifyManifestSources(final Manifest onboardingManifest) {
341 final Set<String> packageFiles = contentHandler.getFileList();
342 final List<String> sources = internalFilesFilter.filter(onboardingManifest.getSources());
343 verifyFilesExist(packageFiles, sources, MANIFEST_SOURCE);
344 final Map<String, List<String>> nonManoArtifacts = onboardingManifest.getNonManoSources();
345 final List<String> nonManoValidFilePaths = new ArrayList<>();
346 nonManoArtifacts.forEach((nonManoType, files) -> {
347 final List<String> internalNonManoFileList = internalFilesFilter.filter(files);
348 nonManoValidFilePaths.addAll(internalNonManoFileList);
349 final NonManoArtifactType nonManoArtifactType = NonManoArtifactType.parse(nonManoType).orElse(null);
350 if (nonManoArtifactType == ONAP_PM_DICTIONARY || nonManoArtifactType == ONAP_VES_EVENTS) {
351 internalNonManoFileList.forEach(this::validateYaml);
352 } else if (nonManoArtifactType == ONAP_SW_INFORMATION) {
353 validateSoftwareInformationNonManoArtifact(files);
354 } else if (nonManoArtifactType == ONAP_CNF_HELM) {
355 validateOnapCnfHelmNonManoEntry(files);
358 verifyFilesExist(packageFiles, nonManoValidFilePaths, MANIFEST_NON_MANO_SOURCE);
359 final Set<String> allReferredFiles = new HashSet<>();
360 allReferredFiles.addAll(sources);
361 allReferredFiles.addAll(nonManoValidFilePaths);
362 verifyFilesBeingReferred(allReferredFiles, packageFiles);
365 private void validateSoftwareInformationNonManoArtifact(final List<String> files) {
366 if (CollectionUtils.isEmpty(files)) {
367 reportError(ErrorLevel.ERROR, Messages.EMPTY_SW_INFORMATION_NON_MANO_ERROR.getErrorMessage());
370 if (files.size() != 1) {
371 final String formattedFileList = files.stream().map(filePath -> String.format("'%s'", filePath)).collect(Collectors.joining(", "));
372 reportError(ErrorLevel.ERROR, Messages.UNIQUE_SW_INFORMATION_NON_MANO_ERROR.formatMessage(formattedFileList));
375 final String swInformationFilePath = files.get(0);
376 final byte[] swInformationYaml = contentHandler.getFileContent(swInformationFilePath);
377 final Optional<PnfSoftwareInformation> parsedYaml = SoftwareInformationArtifactYamlParser.parse(swInformationYaml);
378 if (!parsedYaml.isPresent()) {
379 reportError(ErrorLevel.ERROR, Messages.INVALID_SW_INFORMATION_NON_MANO_ERROR.formatMessage(swInformationFilePath));
381 final PnfSoftwareInformation pnfSoftwareInformation = parsedYaml.get();
382 if (!pnfSoftwareInformation.isValid()) {
383 reportError(ErrorLevel.ERROR, Messages.INCORRECT_SW_INFORMATION_NON_MANO_ERROR.formatMessage(swInformationFilePath));
389 * Validates if a YAML file has the correct extension, is not empty and the content is a valid YAML. Reports each error found.
391 * @param filePath the file path inside the package
393 private void validateYaml(final String filePath) {
394 if (!contentHandler.containsFile(filePath)) {
397 final String fileExtension = getFileExtension(filePath);
398 if (!"yaml".equalsIgnoreCase(fileExtension) && !"yml".equalsIgnoreCase(fileExtension)) {
399 reportError(ErrorLevel.ERROR, Messages.INVALID_YAML_EXTENSION.formatMessage(filePath));
402 try (final InputStream fileContent = contentHandler.getFileContentAsStream(filePath)) {
403 if (fileContent == null) {
404 reportError(ErrorLevel.ERROR, Messages.EMPTY_YAML_FILE_1.formatMessage(filePath));
407 new Yaml().loadAll(fileContent).iterator().next();
408 } catch (final IOException e) {
409 final String errorMsg = Messages.FILE_LOAD_CONTENT_ERROR.formatMessage(filePath);
410 reportError(ErrorLevel.ERROR, errorMsg);
411 LOGGER.debug(errorMsg, e);
412 } catch (final Exception e) {
413 final String message = Messages.INVALID_YAML_FORMAT_1.formatMessage(filePath, e.getMessage());
414 LOGGER.debug(message, e);
415 reportError(ErrorLevel.ERROR, message);
420 * Checks if all package files are referred in manifest. Reports missing references.
422 * @param referredFileSet the list of referred files path
423 * @param packageFileSet the list of package file path
425 private void verifyFilesBeingReferred(final Set<String> referredFileSet, final Set<String> packageFileSet) {
426 packageFileSet.forEach(filePath -> {
427 if (!isManifestFile(filePath) && !referredFileSet.contains(filePath)) {
428 reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_MANIFEST_REFERENCE.getErrorMessage(), filePath));
433 private boolean isManifestFile(final String filePath) {
434 return filePath.equals(toscaMetadata.getMetaEntries().get(ETSI_ENTRY_MANIFEST.getName()));
437 private void validateOtherEntries(final String folderPath) {
438 if (!verifyFoldersExist(folderList, folderPath)) {
439 reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_OPTIONAL_FOLDERS.getErrorMessage(), folderPath));
443 private void validateCertificate(final String file) {
444 final Set<String> packageFiles = contentHandler.getFileList();
445 if (!verifyFileExist(packageFiles, file)) {
446 reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_METADATA_FILES.getErrorMessage(), file, file));
450 private boolean verifyFoldersExist(final Set<String> folderList, final String folderPath) {
451 return folderList.contains(folderPath + "/");
454 private void verifyFilesExist(final Set<String> existingFiles, final List<String> sources, final String type) {
455 sources.forEach(file -> {
456 if (!existingFiles.contains(file)) {
457 reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_MANIFEST_SOURCE.getErrorMessage(), type, file));
462 private boolean verifyFileExist(final Set<String> existingFiles, final String file) {
463 return existingFiles.contains(file);
466 private void validateChangeLog(final String filePath) {
467 if (!verifyFileExists(contentHandler.getFileList(), filePath)) {
468 reportError(ErrorLevel.ERROR, String.format(Messages.MISSING_METADATA_FILES.getErrorMessage(), filePath));
472 protected void reportError(final ErrorLevel errorLevel, final String errorMessage) {
473 errorsByFile.add(new ErrorMessage(errorLevel, errorMessage));
476 protected boolean validMetaLimit(Map<String, String> metadata) {
477 return metadata.size() == MANIFEST_METADATA_LIMIT;
480 protected ImmutableSet<String> getManifestMetadata(final Map<String, String> metadata) {
481 return isPnfMetadata(metadata) ? MANIFEST_PNF_METADATA : MANIFEST_VNF_METADATA;
484 protected void handleOtherEntry(final Map.Entry<String, String> entry) {
485 reportError(ErrorLevel.ERROR, Messages.METADATA_UNSUPPORTED_ENTRY.formatMessage(entry.getKey()));
486 LOGGER.warn(Messages.METADATA_UNSUPPORTED_ENTRY.getErrorMessage(), entry.getKey());
489 private void validatePmDictionaryContentsAgainstSchema() {
490 final Stream<byte[]> pmDictionaryFiles = new FileExtractor(getEtsiEntryManifestPath(), contentHandler).findFiles(ONAP_PM_DICTIONARY);
491 new PMDictionaryValidator().validate(pmDictionaryFiles, (String message) -> reportError(ErrorLevel.ERROR, message));
494 private String getEtsiEntryManifestPath() {
495 return toscaMetadata.getMetaEntries().get(ETSI_ENTRY_MANIFEST.getName());
499 * Validates if onap_cnf_helm non_mano type points to a file
503 private void validateOnapCnfHelmNonManoEntry(final List<String> files) {
504 if (CollectionUtils.isEmpty(files)) {
505 reportError(ErrorLevel.ERROR, Messages.EMPTY_ONAP_CNF_HELM_NON_MANO_ERROR.getErrorMessage());
508 if (files.size() != 1) {
509 final String formattedFileList = files.stream().map(filePath -> String.format("'%s'", filePath)).collect(Collectors.joining(", "));
510 reportError(ErrorLevel.ERROR, Messages.UNIQUE_ONAP_CNF_HELM_NON_MANO_ERROR.formatMessage(formattedFileList));
515 public ValidationResult validate(final FileContentHandler csarContent) {
516 this.contentHandler = (OnboardingPackageContentHandler) csarContent;
517 this.folderList = contentHandler.getFolderList();
518 parseToscaMetadata();
519 verifyMetadataFile();
520 if (packageHasCertificate()) {
523 validatePmDictionaryContentsAgainstSchema();
524 final var csarValidationResult = new CsarValidationResult();
525 errorsByFile.forEach(csarValidationResult::addError);
526 return csarValidationResult;
530 public boolean appliesTo(final String model) {
531 return model == null;
535 public int getOrder() {