/* * Copyright (c) 2014 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.util; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.annotation.concurrent.Immutable; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.CapabilityName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.LabelName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.QualityName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RelatorName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RequirementName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TargetName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ConsumerSelectionRelator; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Label; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ProviderSelectionRelator; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Relator; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.capabilities.Capability; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.qualities.Quality; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.requirements.Requirement; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.target.selector.QualityMatcher; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.target.selector.quality.matcher.MatcherQuality; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Target; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.consumer.matchers.group.identification.constraints.group.requirement.constraint._case.RequirementMatcher; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.consumer.matchers.group.identification.constraints.group.requirement.constraint._case.requirement.matcher.MatcherRequirement; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.provider.matchers.group.identification.constraints.group.capability.constraint._case.CapabilityMatcher; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.provider.matchers.group.identification.constraints.group.capability.constraint._case.capability.matcher.MatcherCapability; /** * Utilities related to matchers and labels */ public class MatcherUtils { private MatcherUtils() { throw new UnsupportedOperationException("Cannot create an instance"); } /** * Apply a quality matcher to a normalized target * * @param matcher * the {@link QualityMatcher} to apply * @param target * the {@link Target} to match against * @return <code>true</code> if the matcher matches the target */ public static boolean applyQualityMatcher(QualityMatcher matcher, Target target) { List<MatcherLabel<QualityName, TargetName>> mls = new ArrayList<>(); if (matcher.getMatcherQuality() != null) { for (MatcherQuality ml : matcher.getMatcherQuality()) { mls.add(new MatcherLabel<>(ml.getName(), ml.getTargetNamespace())); } } Set<QualityName> toMatch = new HashSet<>(); for (Quality q : target.getQuality()) { toMatch.add(q.getName()); } return applyLabelMatcher(mls, matcher.getMatchType(), toMatch, target.getName()); } /** * Apply a requirement matcher to a normalized consumer selection relator * * @param matcher * the {@link RequirementMatcher} to apply * @param relator * the {@link ConsumerSelectionRelator} to match against * @return <code>true</code> if the matcher matches the target */ public static boolean applyReqMatcher(RequirementMatcher matcher, ConsumerSelectionRelator relator) { List<MatcherLabel<RequirementName, SelectorName>> mls = new ArrayList<>(); if (matcher.getMatcherRequirement() != null) { for (MatcherRequirement ml : matcher.getMatcherRequirement()) { mls.add(new MatcherLabel<>(ml.getName(), ml.getSelectorNamespace())); } } Set<RequirementName> toMatch = new HashSet<>(); for (Requirement q : relator.getRequirement()) { toMatch.add(q.getName()); } return applyLabelMatcher(mls, matcher.getMatchType(), toMatch, relator.getName()); } /** * Apply a capability matcher to a normalized provider selection relator * * @param matcher * the {@link RequirementMatcher} to apply * @param relator * the {@link ProviderSelectionRelator} to match against * @return <code>true</code> if the matcher matches the target */ public static boolean applyCapMatcher(CapabilityMatcher matcher, ProviderSelectionRelator relator) { List<MatcherLabel<CapabilityName, SelectorName>> mls = new ArrayList<>(); if (matcher.getMatcherCapability() != null) { for (MatcherCapability ml : matcher.getMatcherCapability()) { mls.add(new MatcherLabel<>(ml.getName(), ml.getSelectorNamespace())); } } Set<CapabilityName> toMatch = new HashSet<>(); for (Capability q : relator.getCapability()) { toMatch.add(q.getName()); } return applyLabelMatcher(mls, matcher.getMatchType(), toMatch, relator.getName()); } /** * Functional interface used for generic label methods * * @author readams * * @param <L> * The specific label type * @param <LN> * the related label name type */ public interface GetLabelName<L extends Label, LN extends LabelName> { /** * Get the appropriate typed name for the given label * * @param label * the label * @return the name */ public LN getName(L label); } /** * A {@link GetLabelName} for qualities */ public static final GetLabelName<Quality, QualityName> getQualityName = new GetLabelName<Quality, QualityName>() { @Override public QualityName getName(Quality label) { return label.getName(); } }; /** * A {@link GetLabelName} for matcher qualities */ public static final GetLabelName<MatcherQuality, QualityName> getMatcherQualityName = new GetLabelName<MatcherQuality, QualityName>() { @Override public QualityName getName(MatcherQuality label) { return label.getName(); } }; /** * A {@link GetLabelName} for requirements */ public static final GetLabelName<Requirement, RequirementName> getRequirementName = new GetLabelName<Requirement, RequirementName>() { @Override public RequirementName getName(Requirement label) { return label.getName(); } }; /** * A {@link GetLabelName} for matcher requirements */ public static final GetLabelName<MatcherRequirement, RequirementName> getMatcherRequirementName = new GetLabelName<MatcherRequirement, RequirementName>() { @Override public RequirementName getName(MatcherRequirement label) { return label.getName(); } }; /** * A {@link GetLabelName} for capabilities */ public static final GetLabelName<Capability, CapabilityName> getCapabilityName = new GetLabelName<Capability, CapabilityName>() { @Override public CapabilityName getName(Capability label) { return label.getName(); } }; /** * A {@link GetLabelName} for matcher capabilities */ public static final GetLabelName<MatcherCapability, CapabilityName> getMatcherCapabilityName = new GetLabelName<MatcherCapability, CapabilityName>() { @Override public CapabilityName getName(MatcherCapability label) { return label.getName(); } }; /** * A {@link GetLabelName} for capabilities */ public static final GetLabelName<Condition, ConditionName> getConditionName = new GetLabelName<Condition, ConditionName>() { @Override public ConditionName getName(Condition label) { return label.getName(); } }; @Immutable private static class MatcherLabel<LN extends LabelName, NS extends RelatorName> { final LN name; final NS namespace; public MatcherLabel(LN name, NS namespace) { super(); this.name = name; this.namespace = namespace; } } private static <LN extends LabelName, L extends Label, NS extends RelatorName, R extends Relator> boolean applyLabelMatcher(Collection<MatcherLabel<LN, NS>> matcherLabels, MatchType matchType, Set<LN> toMatch, NS matchNamespace) { int matches = 0; int matchersize = 0; if (matcherLabels != null) { matchersize = matcherLabels.size(); for (MatcherLabel<LN, NS> matcherLabel : matcherLabels) { if (matcherLabel.namespace != null && !matcherLabel.namespace.equals(matchNamespace)) continue; if (!toMatch.contains(matcherLabel.name)) continue; matches += 1; } } if (matchType == null) matchType = MatchType.All; switch (matchType) { case Any: return matches > 0; case None: return matches == 0; case All: default: return matches == matchersize; } } }