/*
* Copyright 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.
*/
package org.onap.cvc.csar;
import org.apache.commons.lang3.tuple.Pair;
import org.onap.cli.fw.error.OnapCommandException;
import org.onap.cvc.csar.oclip.Command;
import org.onap.cvc.csar.oclip.CommandFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class CsarValidator {
private final CommandFactory commandFactory;
private final List ignoreCodes;
private final List activeRules;
private final ReleasesResolver releasesResolver;
private final RulesToValidate rulesToValidate;
public CsarValidator(CommandFactory commandFactory, List ignoreCodes,
List activeRules, ReleasesResolver releasesResolver,
RulesToValidate rulesToValidate) {
this.commandFactory = commandFactory;
this.ignoreCodes = ignoreCodes;
this.activeRules = activeRules;
this.releasesResolver = releasesResolver;
this.rulesToValidate = rulesToValidate;
}
Pair> validate(ValidationContext validationContext) {
boolean overallPass = true;
List results = new ArrayList<>();
final List rules = getRulesToExecute();
for (String rule : rules) {
final Pair> pair = executeValidation(releasesResolver, ignoreCodes, rule, validationContext);
overallPass &= pair.getLeft();
results.addAll(pair.getRight());
}
return Pair.of(overallPass, results);
}
private List getRulesToExecute() {
final List rulesToExecute = rulesToValidate.get();
return activeRules.stream().filter(
it -> rulesToExecute.isEmpty() || rulesToExecute.contains(it)
).collect(Collectors.toList());
}
private Pair> executeValidation(
ReleasesResolver releasesResolver, List ignoreCodes,
String reqName, ValidationContext validationContext) {
boolean overallPass = true;
List results = new ArrayList<>();
VTPValidateCSAR.CSARValidation.Result result = new VTPValidateCSAR.CSARValidation.Result();
result.setVnfreqName(reqName);
try {
Command cmd = getCommand(reqName, validationContext);
if (releasesResolver.resolveWithAncestors(validationContext.getRelease()).contains(cmd.getRelease())) {
final List errors = cmd.run();
result.setDescription(cmd.getDescription());
final Pair, List> segregateErrors = segregate(errors, ignoreCodes, reqName);
overallPass = segregateErrors.getLeft().isEmpty();
result.addErrors(segregateErrors.getLeft());
result.addErrorsAsWarnings(segregateErrors.getRight());
result.setPassed(result.getErrors().isEmpty());
results.add(result);
}
} catch (Exception e) {
result.setPassed(false);
overallPass = false;
result.addError(new CSARArchive.CSARErrorUnknown(e.getMessage()));
results.add(result);
}
return Pair.of(overallPass, results);
}
private Command getCommand(String reqName, ValidationContext validationContext) throws OnapCommandException {
return validationContext.isPnf() ? commandFactory.createForPnf(reqName, validationContext.getPathToCsar(), validationContext.getProduct()) : commandFactory.createForVnf(reqName, validationContext.getPathToCsar(), validationContext.getProduct());
}
private Pair, List> segregate(
List errors, List ignoreCodes, String reqName){
final List errorsList = new ArrayList<>();
final List warningsList = new ArrayList<>();
for (CSARArchive.CSARError error : errors) {
if (!isErrorIgnored(ignoreCodes, reqName, error)) {
errorsList.add(error);
} else {
warningsList.add(error);
}
}
return Pair.of(errorsList,warningsList);
}
private boolean isErrorIgnored(List ignoreCodes, String reqName, CSARArchive.CSARError error) {
return ignoreCodes.contains(error.getCode()) || ignoreCodes.contains(reqName + "-" + error.getCode());
}
public static class ValidationContext {
private final String pathToCsar;
private final String product;
private final String release;
private final boolean isPnf;
public ValidationContext(String pathToCsar, String product, String release, boolean isPnf) {
this.pathToCsar = pathToCsar;
this.product = product;
this.release = release;
this.isPnf = isPnf;
}
public String getPathToCsar() {
return pathToCsar;
}
public String getProduct() {
return product;
}
public String getRelease() {
return release;
}
public boolean isPnf() {
return isPnf;
}
}
}