/* * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.groupbasedpolicy.sf; import static com.google.common.base.Preconditions.checkNotNull; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.groupbasedpolicy.api.ValidationResult; import org.opendaylight.groupbasedpolicy.api.Validator; import org.opendaylight.groupbasedpolicy.dto.ValidationResultBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.ParameterType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.Int; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.Range; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.String; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueInRange; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported.range.value.fields.SupportedRangeValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported.string.value.fields.SupportedStringValueBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; public class ClassifierInstanceValidator implements Validator<ClassifierInstance> { private static final Logger LOG = LoggerFactory.getLogger(ClassifierInstanceValidator.class); private final Map<ParameterName, Optional<ParameterType>> parameterByName = new HashMap<>(); private final ClassifierDefinitionId classifierDefinitionId; private final ClassifierDefinitionId parentClassifierDefinitionId; private final RendererName rendererName; private ClassifierInstanceValidator parentValidator; public ClassifierInstanceValidator(SupportedClassifierDefinition constraint, RendererName rendererName) { this.rendererName = checkNotNull(rendererName); classifierDefinitionId = checkNotNull(constraint.getClassifierDefinitionId()); parentClassifierDefinitionId = constraint.getParentClassifierDefinitionId(); if (constraint.getSupportedParameterValues() != null) { for (SupportedParameterValues supportedParams : constraint.getSupportedParameterValues()) { ParameterName parameterName = checkNotNull(supportedParams.getParameterName()); ParameterType parameterType = supportedParams.getParameterType(); parameterByName.put(parameterName, Optional.fromNullable(parameterType)); } } } @Override public ValidationResult validate(ClassifierInstance ci) { for (ParameterValue param : ci.getParameterValue()) { ValidationResult validationResult = validate(param, ci.getName()); if (!validationResult.isValid()) { return validationResult; } } return new ValidationResultBuilder().success().build(); } public ValidationResult validate(ParameterValue param, ClassifierName ciName) { ParameterName paramName = param.getName(); Optional<ParameterType> potentialParamConstraint = parameterByName.get(paramName); if (potentialParamConstraint == null) { // unknown parameter for this validator - let's try validate in parent if (parentValidator != null) { return parentValidator.validate(param, ciName); } return createFailedResult(ciName, param, "is not supported"); } if (!potentialParamConstraint.isPresent()) { LOG.info("There is no constraint for parameter {}. \nTherefore the parameter is considered as valid.", param); return new ValidationResultBuilder().success().build(); } ParameterType paramConstraint = potentialParamConstraint.get(); if (paramConstraint instanceof Int) { boolean paramValid = isParamValid(param, (Int) paramConstraint); if (!paramValid) { return createFailedResultForNotValidParam(ciName, param); } } else if (paramConstraint instanceof Range) { boolean paramValid = isParamValid(param, (Range) paramConstraint); if (!paramValid) { return createFailedResultForNotValidParam(ciName, param); } } else if (paramConstraint instanceof String) { boolean paramValid = isParamValid(param, (String) paramConstraint); if (!paramValid) { return createFailedResultForNotValidParam(ciName, param); } } return new ValidationResultBuilder().success().build(); } private boolean isParamValid(ParameterValue param, Int constraint) { Long value = param.getIntValue(); if (value == null) { return false; } if (constraint.getSupportedIntValue() != null && constraint.getSupportedIntValue().contains(new SupportedIntValueBuilder().setValue(value).build())) { return true; } List<SupportedIntValueInRange> intRangeValues = constraint.getSupportedIntValueInRange(); if (intRangeValues != null) { for (SupportedIntValueInRange supportedValue : intRangeValues) { if (supportedValue.getMin() <= value && supportedValue.getMax() >= value) { return true; } } } return false; } private boolean isParamValid(ParameterValue param, Range constraint) { RangeValue value = param.getRangeValue(); if (value == null) { return false; } List<SupportedRangeValue> intRangeValues = constraint.getSupportedRangeValue(); if (intRangeValues != null) { for (SupportedRangeValue supportedValue : intRangeValues) { if (supportedValue.getMin() <= value.getMin() && supportedValue.getMax() >= value.getMax()) { return true; } } } return false; } private boolean isParamValid(ParameterValue param, String constraint) { java.lang.String value = param.getStringValue(); if (value == null) { return false; } if (constraint.getSupportedStringValue() != null && constraint.getSupportedStringValue() .contains(new SupportedStringValueBuilder().setValue(value).build())) { return true; } return false; } private ValidationResult createFailedResultForNotValidParam(ClassifierName ciName, ParameterValue param) { return createFailedResult(ciName, param, "is not valid"); } private ValidationResult createFailedResult(ClassifierName ciName, ParameterValue param, java.lang.String cause) { StringBuilder sb = new StringBuilder("Error in classifier-instance ").append(ciName.getValue()) .append(". Parameter ") .append(param.getName().getValue()) .append(" with value "); if (param.getIntValue() != null) { sb.append(param.getIntValue()); } else if (param.getRangeValue() != null) { RangeValue rangeValue = param.getRangeValue(); sb.append("min:").append(rangeValue.getMin()).append(" max:").append(rangeValue.getMax()); } else if (param.getStringValue() != null) { sb.append(param.getStringValue()); } sb.append(" ").append(cause).append(".").toString(); return new ValidationResultBuilder().failed().setMessage(sb.toString()).build(); } public boolean containsParamsForValidation() { for (Optional<ParameterType> paramValue : parameterByName.values()) { if (paramValue.isPresent()) { return true; } } return false; } public @Nonnull RendererName getRendererName() { return rendererName; } public @Nonnull Set<ParameterName> getSupportedParameters() { return parameterByName.keySet(); } public @Nonnull ClassifierDefinitionId getClassifierDefinitionId() { return classifierDefinitionId; } public @Nullable ClassifierDefinitionId getParentClassifierDefinitionId() { return parentClassifierDefinitionId; } public @Nullable Validator<ClassifierInstance> getParentValidator() { return parentValidator; } public void setParentValidator(@Nullable ClassifierInstanceValidator parentValidator) { this.parentValidator = parentValidator; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((parameterByName == null) ? 0 : parameterByName.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ClassifierInstanceValidator other = (ClassifierInstanceValidator) obj; if (parameterByName == null) { if (other.parameterByName != null) return false; } else if (!parameterByName.equals(other.parameterByName)) return false; return true; } @Override public java.lang.String toString() { return "ClassifierInstanceValidator [parameterByName=" + parameterByName + "]"; } }