aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org
diff options
context:
space:
mode:
authorJan Malkiewicz <jan.malkiewicz@nokia.com>2021-02-09 08:39:23 +0100
committerChristophe Closset <christophe.closset@intl.att.com>2021-02-20 07:07:31 +0000
commit372c2470e613128f1e33cfc581ea2c5b1b732d2b (patch)
tree7204e30f8ea609a057ec3e4449d1abfc4d4b4c27 /openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org
parent6068ce140c9a65f13a0bd245c9b9a50befaddc32 (diff)
Add validation of manifest for helm packages.
For ONAP native zip packages added validation of manifest file. HELM package is only valid if: * isBase flag is set to 'true' for exactly one helm entry * isBase flag is present for all helm entries Zip package is considered to be a helm package if it contains HELM entries but does not contain any HEAT entries (however it may contains entries of other types). Refactored method OnboardingPackageProcessor.processPackage(): * simplified logic * enhanced exception handling Issue-ID: SDC-3185 Signed-off-by: Jan Malkiewicz <jan.malkiewicz@nokia.com> Change-Id: Ica3b1f1504ce4fc3a671c4b8fa8de2bf0236bd77
Diffstat (limited to 'openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org')
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/ManifestAnalyzer.java73
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java217
-rw-r--r--openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/validation/CnfPackageValidator.java77
3 files changed, 290 insertions, 77 deletions
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/ManifestAnalyzer.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/ManifestAnalyzer.java
new file mode 100644
index 0000000000..ecb3ac62ed
--- /dev/null
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/ManifestAnalyzer.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nokia
+ * ================================================================================
+ * 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.onboarding;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.openecomp.sdc.heat.datatypes.manifest.FileData;
+import org.openecomp.sdc.heat.datatypes.manifest.FileData.Type;
+import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
+
+public class ManifestAnalyzer {
+
+ private final ManifestContent manifest;
+
+ private final static Set<Type> HEAT_TYPES = Collections.singleton(Type.HEAT);
+
+ private final static Set<Type> HELM_TYPES = Collections.singleton(Type.HELM);
+
+ public ManifestAnalyzer(ManifestContent manifest) {
+ this.manifest = manifest;
+ }
+
+ public boolean hasHeatEntries() {
+ return hasEntriesOfType(HEAT_TYPES);
+ }
+
+ public boolean hasHelmEntries() {
+ return hasEntriesOfType(HELM_TYPES);
+ }
+
+ public List<FileData> getHelmEntries() {
+ List<FileData> entries = new ArrayList<>();
+ if (hasFileData()) {
+ for (FileData d : manifest.getData()) {
+ if (HELM_TYPES.contains(d.getType())) {
+ entries.add(d);
+ }
+ }
+ }
+ return entries;
+ }
+
+ private boolean hasEntriesOfType(Set<Type> types) {
+ boolean result = false;
+ if (hasFileData()) {
+ result = manifest.getData().stream().anyMatch(fileData -> types.contains(fileData.getType()));
+ }
+ return result;
+ }
+
+ private boolean hasFileData() {
+ return manifest != null && manifest.getData() != null && !manifest.getData().isEmpty();
+ }
+}
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java
index a40f2ebd30..e863f34696 100644
--- a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/OnboardingPackageProcessor.java
@@ -1,6 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2019 Nordix Foundation
+ * Copyright (C) 2021 Nokia
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +20,7 @@
package org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding;
+import static org.openecomp.sdc.common.errors.Messages.COULD_NOT_READ_MANIFEST_FILE;
import static org.openecomp.sdc.common.errors.Messages.PACKAGE_EMPTY_ERROR;
import static org.openecomp.sdc.common.errors.Messages.PACKAGE_INVALID_ERROR;
import static org.openecomp.sdc.common.errors.Messages.PACKAGE_INVALID_EXTENSION;
@@ -35,6 +37,7 @@ import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -47,89 +50,157 @@ import org.apache.commons.io.FilenameUtils;
import org.openecomp.core.utilities.file.FileContentHandler;
import org.openecomp.core.utilities.json.JsonUtil;
import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
+import org.openecomp.sdc.common.utils.CommonUtil;
import org.openecomp.sdc.common.utils.SdcCommon;
import org.openecomp.sdc.common.zip.exception.ZipException;
-import org.openecomp.sdc.common.utils.CommonUtil;
import org.openecomp.sdc.datatypes.error.ErrorLevel;
import org.openecomp.sdc.datatypes.error.ErrorMessage;
import org.openecomp.sdc.heat.datatypes.manifest.FileData;
import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
+import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.validation.CnfPackageValidator;
import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackage;
import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardSignedPackage;
public class OnboardingPackageProcessor {
+
private static final Logger LOGGER = LoggerFactory.getLogger(OnboardingPackageProcessor.class);
private static final String CSAR_EXTENSION = "csar";
private static final String ZIP_EXTENSION = "zip";
- private static boolean helmBase = false;
private final String packageFileName;
private final byte[] packageFileContent;
- private FileContentHandler onboardPackageContentHandler;
- private Set<ErrorMessage> errorMessageSet = new HashSet<>();
- private OnboardPackageInfo onboardPackageInfo;
+ private FileContentHandler packageContent;
+ private final Set<ErrorMessage> errorMessages = new HashSet<>();
+ private final OnboardPackageInfo onboardPackageInfo;
+ private final CnfPackageValidator cnfPackageValidator;
public OnboardingPackageProcessor(final String packageFileName, final byte[] packageFileContent) {
this.packageFileName = packageFileName;
this.packageFileContent = packageFileContent;
+ this.cnfPackageValidator = new CnfPackageValidator();
onboardPackageInfo = processPackage();
}
+ public Optional<OnboardPackageInfo> getOnboardPackageInfo() {
+ return Optional.ofNullable(onboardPackageInfo);
+ }
+
+ public boolean hasErrors() {
+ return !errorMessages.isEmpty();
+ }
+
+ public boolean hasNoErrors() {
+ return errorMessages.isEmpty();
+ }
+
+ public Set<ErrorMessage> getErrorMessages() {
+ return errorMessages;
+ }
+
private OnboardPackageInfo processPackage() {
- if (!hasValidExtension()) {
- final String message = PACKAGE_INVALID_EXTENSION.formatMessage(packageFileName, String.join(", ", CSAR_EXTENSION, ZIP_EXTENSION));
- reportError(ErrorLevel.ERROR, message);
- return null;
- }
- try {
- onboardPackageContentHandler = CommonUtil.getZipContent(packageFileContent);
- } catch (final ZipException e) {
- final String message = PACKAGE_PROCESS_ERROR.formatMessage(packageFileName);
- LOGGER.error(message, e);
- reportError(ErrorLevel.ERROR, message);
- return null;
+ OnboardPackageInfo packageInfo = null;
+ validateFile();
+ if (hasNoErrors()) {
+ final String packageName = FilenameUtils.getBaseName(packageFileName);
+ final String packageExtension = FilenameUtils.getExtension(packageFileName);
+
+ if (hasSignedPackageStructure()) {
+ packageInfo = processSignedPackage(packageName, packageExtension);
+ } else {
+ if (packageExtension.equalsIgnoreCase(CSAR_EXTENSION)) {
+ packageInfo = processCsarPackage(packageName, packageExtension);
+ } else if (packageExtension.equalsIgnoreCase(ZIP_EXTENSION)) {
+ packageInfo = processOnapNativeZipPackage(packageName, packageExtension);
+ }
+ }
}
- if (isPackageEmpty()) {
- final String message = PACKAGE_EMPTY_ERROR.formatMessage(packageFileName);
+ return packageInfo;
+ }
+
+ private void validateFile() {
+ if (!hasValidExtension()) {
+ String message = PACKAGE_INVALID_EXTENSION
+ .formatMessage(packageFileName, String.join(", ", CSAR_EXTENSION, ZIP_EXTENSION));
reportError(ErrorLevel.ERROR, message);
- return null;
+ } else {
+ try {
+ packageContent = CommonUtil.getZipContent(packageFileContent);
+ if (isPackageEmpty()) {
+ String message = PACKAGE_EMPTY_ERROR.formatMessage(packageFileName);
+ reportError(ErrorLevel.ERROR, message);
+ }
+ } catch (final ZipException e) {
+ String message = PACKAGE_PROCESS_ERROR.formatMessage(packageFileName);
+ reportError(ErrorLevel.ERROR, message);
+ LOGGER.error(message, e);
+ }
}
+ }
- final String packageName = FilenameUtils.getBaseName(packageFileName);
- final String packageExtension = FilenameUtils.getExtension(packageFileName);
+ private OnboardPackageInfo processCsarPackage(String packageName, String packageExtension) {
+ OnboardPackage onboardPackage = new OnboardPackage(packageName, packageExtension,
+ ByteBuffer.wrap(packageFileContent), new OnboardingPackageContentHandler(packageContent));
+ return new OnboardPackageInfo(onboardPackage, OnboardingTypesEnum.CSAR);
+ }
- if (hasSignedPackageStructure()) {
- return processSignedPackage(packageName, packageExtension);
- } else {
- if (packageExtension.equalsIgnoreCase(CSAR_EXTENSION)) {
+ private OnboardPackageInfo processOnapNativeZipPackage(String packageName, String packageExtension) {
+ ManifestContent manifest = getManifest();
+ if (manifest != null) {
+ List<String> errors = validateZipPackage(manifest);
+ if (errors.isEmpty()) {
final OnboardPackage onboardPackage = new OnboardPackage(packageName, packageExtension,
- ByteBuffer.wrap(packageFileContent), new OnboardingPackageContentHandler(onboardPackageContentHandler));
- return new OnboardPackageInfo(onboardPackage, OnboardingTypesEnum.CSAR);
- } else if (packageExtension.equalsIgnoreCase(ZIP_EXTENSION)) {
- addDummyHeat();
- final OnboardPackage onboardPackage = new OnboardPackage(packageName, packageExtension,
- ByteBuffer.wrap(packageFileContent), onboardPackageContentHandler);
+ ByteBuffer.wrap(packageFileContent), packageContent);
return new OnboardPackageInfo(onboardPackage, OnboardingTypesEnum.ZIP);
+ } else {
+ errors.forEach(message -> reportError(ErrorLevel.ERROR, message));
+ }
+ } else {
+ reportError(ErrorLevel.ERROR,
+ COULD_NOT_READ_MANIFEST_FILE.formatMessage(SdcCommon.MANIFEST_NAME, packageFileName));
+ }
+ return null;
+ }
+
+ List<String> validateZipPackage(ManifestContent manifest) {
+ ManifestAnalyzer analyzer = new ManifestAnalyzer(manifest);
+ List<String> errors = Collections.emptyList();
+ if (analyzer.hasHelmEntries()) {
+ if (shouldValidateHelmPackage(analyzer)) {
+ errors = cnfPackageValidator.validateHelmPackage(analyzer.getHelmEntries());
}
}
+ addDummyHeat(manifest);
+ return errors;
+ }
- reportError(ErrorLevel.ERROR, PACKAGE_INVALID_ERROR.formatMessage(packageFileName));
- return null;
+ boolean shouldValidateHelmPackage(ManifestAnalyzer analyzer) {
+ return analyzer.hasHelmEntries() && !analyzer.hasHeatEntries();
}
- private void addDummyHeat() {
+ private ManifestContent getManifest() {
+ ManifestContent manifest = null;
+ try (InputStream zipFileManifest = packageContent.getFileContentAsStream(SdcCommon.MANIFEST_NAME)) {
+ manifest = JsonUtil.json2Object(zipFileManifest, ManifestContent.class);
+
+ } catch (Exception e) {
+ final String message = COULD_NOT_READ_MANIFEST_FILE.formatMessage(SdcCommon.MANIFEST_NAME, packageFileName);
+ LOGGER.error(message, e);
+ }
+ return manifest;
+ }
+
+ private void addDummyHeat(ManifestContent manifestContent) {
// temporary fix for adding dummy base
List<FileData> newfiledata = new ArrayList<>();
- try (InputStream zipFileManifest = onboardPackageContentHandler.getFileContentAsStream(SdcCommon.MANIFEST_NAME)) {
- ManifestContent manifestContent =
- JsonUtil.json2Object(zipFileManifest, ManifestContent.class);
+ try {
+ boolean heatBase = false;
for (FileData fileData : manifestContent.getData()) {
if (Objects.nonNull(fileData.getType()) &&
- fileData.getType().equals(FileData.Type.HELM) && fileData.getBase()) {
- helmBase = true;
+ fileData.getType().equals(FileData.Type.HELM) && fileData.getBase()) {
+ heatBase = true;
fileData.setBase(false);
FileData dummyHeat = new FileData();
dummyHeat.setBase(true);
@@ -146,27 +217,28 @@ public class OnboardingPackageProcessor {
String filePath = new File("").getAbsolutePath() + "/resources";
File envFilePath = new File(filePath + "/base_template.env");
File baseFilePath = new File(filePath + "/base_template.yaml");
- try (
- InputStream envStream = new FileInputStream(envFilePath);
- InputStream baseStream = new FileInputStream(baseFilePath);) {
- onboardPackageContentHandler.addFile("base_template_dummy_ignore.env", envStream);
- onboardPackageContentHandler.addFile("base_template_dummy_ignore.yaml", baseStream);
+ try (InputStream envStream = new FileInputStream(envFilePath);
+ InputStream baseStream = new FileInputStream(baseFilePath)) {
+ packageContent.addFile("base_template_dummy_ignore.env", envStream);
+ packageContent.addFile("base_template_dummy_ignore.yaml", baseStream);
} catch (Exception e) {
LOGGER.error("Failed creating input stream {}", e);
}
}
}
- if (helmBase) {
+ if (heatBase) {
manifestContent.getData().addAll(newfiledata);
- InputStream manifestContentStream = new ByteArrayInputStream((JsonUtil.object2Json(manifestContent)).getBytes(StandardCharsets.UTF_8));
- onboardPackageContentHandler.remove(SdcCommon.MANIFEST_NAME);
- onboardPackageContentHandler.addFile(SdcCommon.MANIFEST_NAME, manifestContentStream);
+ InputStream manifestContentStream = new ByteArrayInputStream(
+ (JsonUtil.object2Json(manifestContent)).getBytes(StandardCharsets.UTF_8));
+ packageContent.remove(SdcCommon.MANIFEST_NAME);
+ packageContent.addFile(SdcCommon.MANIFEST_NAME, manifestContentStream);
}
} catch (Exception e) {
final String message = PACKAGE_INVALID_ERROR.formatMessage(packageFileName);
LOGGER.error(message, e);
}
}
+
private boolean hasValidExtension() {
final String packageExtension = FilenameUtils.getExtension(packageFileName);
return packageExtension.equalsIgnoreCase(CSAR_EXTENSION) || packageExtension.equalsIgnoreCase(ZIP_EXTENSION);
@@ -182,12 +254,12 @@ public class OnboardingPackageProcessor {
final String certificateFilePath = findCertificateFilePath().orElse(null);
final OnboardSignedPackage onboardSignedPackage =
new OnboardSignedPackage(packageName, packageExtension, ByteBuffer.wrap(packageFileContent),
- onboardPackageContentHandler, signatureFilePath, internalPackagePath, certificateFilePath);
+ packageContent, signatureFilePath, internalPackagePath, certificateFilePath);
final String internalPackageName = FilenameUtils.getName(internalPackagePath);
final String internalPackageBaseName = FilenameUtils.getBaseName(internalPackagePath);
final String internalPackageExtension = FilenameUtils.getExtension(internalPackagePath);
- final byte[] internalPackageContent = onboardPackageContentHandler.getFileContent(internalPackagePath);
+ final byte[] internalPackageContent = packageContent.getFileContent(internalPackagePath);
final OnboardPackage onboardPackage;
try {
final OnboardingPackageContentHandler fileContentHandler =
@@ -205,19 +277,11 @@ public class OnboardingPackageProcessor {
}
private void reportError(final ErrorLevel errorLevel, final String message) {
- errorMessageSet.add(new ErrorMessage(errorLevel, message));
- }
-
- public boolean hasErrors() {
- return !errorMessageSet.isEmpty();
- }
-
- public Set<ErrorMessage> getErrorMessageSet() {
- return errorMessageSet;
+ errorMessages.add(new ErrorMessage(errorLevel, message));
}
private Optional<String> findInternalPackagePath() {
- return onboardPackageContentHandler.getFileList().stream()
+ return packageContent.getFileList().stream()
.filter(filePath -> {
final String extension = FilenameUtils.getExtension(filePath);
return CSAR_EXTENSION.equalsIgnoreCase(extension) || ZIP_EXTENSION.equalsIgnoreCase(extension);
@@ -227,24 +291,24 @@ public class OnboardingPackageProcessor {
}
private boolean isPackageEmpty() {
- return MapUtils.isEmpty(onboardPackageContentHandler.getFiles());
+ return MapUtils.isEmpty(packageContent.getFiles());
}
private boolean hasSignedPackageStructure() {
- if (MapUtils.isEmpty(onboardPackageContentHandler.getFiles()) || !CollectionUtils.isEmpty(
- onboardPackageContentHandler.getFolderList())) {
+ if (MapUtils.isEmpty(packageContent.getFiles()) || !CollectionUtils.isEmpty(
+ packageContent.getFolderList())) {
return false;
}
- final int numberOfFiles = onboardPackageContentHandler.getFileList().size();
+ final int numberOfFiles = packageContent.getFileList().size();
if (numberOfFiles == 2) {
- return hasOneInternalPackageFile(onboardPackageContentHandler) &&
- hasOneSignatureFile(onboardPackageContentHandler);
+ return hasOneInternalPackageFile(packageContent) &&
+ hasOneSignatureFile(packageContent);
}
if (numberOfFiles == 3) {
- return hasOneInternalPackageFile(onboardPackageContentHandler) &&
- hasOneSignatureFile(onboardPackageContentHandler) &&
- hasOneCertificateFile(onboardPackageContentHandler);
+ return hasOneInternalPackageFile(packageContent) &&
+ hasOneSignatureFile(packageContent) &&
+ hasOneCertificateFile(packageContent);
}
return false;
@@ -272,20 +336,19 @@ public class OnboardingPackageProcessor {
}
private Optional<String> findSignatureFilePath() {
- final Map<String, byte[]> files = onboardPackageContentHandler.getFiles();
+ final Map<String, byte[]> files = packageContent.getFiles();
return files.keySet().stream()
- .filter(fileName -> ALLOWED_SIGNATURE_EXTENSIONS.contains(FilenameUtils.getExtension(fileName).toLowerCase()))
+ .filter(
+ fileName -> ALLOWED_SIGNATURE_EXTENSIONS.contains(FilenameUtils.getExtension(fileName).toLowerCase()))
.findFirst();
}
private Optional<String> findCertificateFilePath() {
- final Map<String, byte[]> files = onboardPackageContentHandler.getFiles();
+ final Map<String, byte[]> files = packageContent.getFiles();
return files.keySet().stream()
- .filter(fileName -> ALLOWED_CERTIFICATE_EXTENSIONS.contains(FilenameUtils.getExtension(fileName).toLowerCase()))
+ .filter(
+ fileName -> ALLOWED_CERTIFICATE_EXTENSIONS.contains(FilenameUtils.getExtension(fileName).toLowerCase()))
.findFirst();
}
- public Optional<OnboardPackageInfo> getOnboardPackageInfo() {
- return Optional.ofNullable(onboardPackageInfo);
- }
}
diff --git a/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/validation/CnfPackageValidator.java b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/validation/CnfPackageValidator.java
new file mode 100644
index 0000000000..8520672cd3
--- /dev/null
+++ b/openecomp-be/backend/openecomp-sdc-vendor-software-product-manager/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/impl/onboarding/validation/CnfPackageValidator.java
@@ -0,0 +1,77 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nokia
+ * ================================================================================
+ * 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.onboarding.validation;
+
+import static org.openecomp.sdc.common.errors.Messages.MANIFEST_VALIDATION_HELM_IS_BASE_MISSING;
+import static org.openecomp.sdc.common.errors.Messages.MANIFEST_VALIDATION_HELM_IS_BASE_NOT_SET;
+import static org.openecomp.sdc.common.errors.Messages.MANIFEST_VALIDATION_HELM_IS_BASE_NOT_UNIQUE;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.openecomp.sdc.heat.datatypes.manifest.FileData;
+
+public class CnfPackageValidator {
+
+ public List<String> validateHelmPackage(List<FileData> modules) {
+ List<String> messages = Collections.emptyList();
+
+ if (modules != null && !modules.isEmpty()) {
+ Stats stats = calculateStats(modules);
+ messages = createErrorMessages(stats);
+ }
+
+ return messages;
+ }
+
+ private Stats calculateStats(List<FileData> modules) {
+ Stats stats = new Stats();
+ for (FileData mod : modules) {
+ if (mod.getBase() == null) {
+ stats.without++;
+ } else if (mod.getBase()) {
+ stats.base++;
+ }
+ }
+ return stats;
+ }
+
+ private List<String> createErrorMessages(Stats stats) {
+ List<String> messages = new ArrayList<>();
+
+ if (stats.without > 0) {
+ messages.add(MANIFEST_VALIDATION_HELM_IS_BASE_MISSING.formatMessage(stats.without));
+ }
+
+ if (stats.base == 0) {
+ messages.add(MANIFEST_VALIDATION_HELM_IS_BASE_NOT_SET.getErrorMessage());
+ } else if (stats.base > 1) {
+ messages.add(MANIFEST_VALIDATION_HELM_IS_BASE_NOT_UNIQUE.getErrorMessage());
+ }
+
+ return messages;
+ }
+
+ private static class Stats {
+
+ private int base = 0;
+ private int without = 0;
+ }
+}