2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.groupbasedpolicy.util;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.List;
19 import org.opendaylight.groupbasedpolicy.dto.ConditionSet;
20 import org.opendaylight.groupbasedpolicy.dto.EgKey;
21 import org.opendaylight.groupbasedpolicy.dto.EndpointConstraint;
22 import org.opendaylight.groupbasedpolicy.dto.Policy;
23 import org.opendaylight.groupbasedpolicy.dto.RuleGroup;
24 import org.opendaylight.groupbasedpolicy.util.ContractResolverUtils.ContractMatch;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcher;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.GroupIdentificationConstraints;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.group.identification.constraints.GroupRequirementConstraintCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.group.identification.constraints.group.requirement.constraint._case.RequirementMatcher;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.GroupCapabilityConstraintCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.group.capability.constraint._case.CapabilityMatcher;
40 import com.google.common.collect.HashBasedTable;
41 import com.google.common.collect.ImmutableSet;
42 import com.google.common.collect.Table;
43 import com.google.common.collect.Table.Cell;
46 class SubjectResolverUtils {
48 private SubjectResolverUtils() {
49 throw new UnsupportedOperationException("Cannot create an instance");
53 * Choose the set of subjects that in scope for each possible set of
56 // TODO Li msunal do we really need contractMatches to be a type Table<EgKey, EgKey, List<ContractMatch>>
57 // it should be sufficient to be just List<ContractMatch>
58 static Table<EgKey, EgKey, Policy> selectSubjects(
59 Table<EgKey, EgKey, List<ContractMatch>> contractMatches, Map<EgKey, Set<ConditionSet>> egConditions) {
60 // TODO: Note that it's possible to further simplify the resulting
62 // in the case of things like repeated rules, condition sets that
63 // cover other condition sets, etc. This would be a good thing to do
65 Table<EgKey, EgKey, Policy> policy = HashBasedTable.create();
67 for (List<ContractMatch> matches : contractMatches.values()) {
68 for (ContractMatch match : matches) {
69 List<Clause> clauses = match.contract.getClause();
73 List<Subject> subjectList = match.contract.getSubject();
74 if (subjectList == null)
77 EgKey ckey = new EgKey(match.consumerTenant.getId(),
78 match.consumer.getId());
79 EgKey pkey = new EgKey(match.providerTenant.getId(),
80 match.provider.getId());
81 Policy existing = policy.get(ckey, pkey);
83 HashMap<SubjectName, Subject> subjects = new HashMap<>();
84 for (Subject s : subjectList) {
85 subjects.put(s.getName(), s);
88 Table<EndpointConstraint, EndpointConstraint, List<Subject>> subjectMap =
89 HashBasedTable.create();
91 for (Clause clause : clauses) {
92 if (clause.getSubjectRefs() != null &&
93 clauseMatchesByGroupReqAndCapConstraints(clause, match)) {
94 ConditionSet consCSet = buildConsConditionSet(clause);
95 addConditionSet(ckey, consCSet, egConditions);
96 EndpointConstraint consEpConstraint = new EndpointConstraint(consCSet,
97 clause.getConsumerMatchers() == null ? null : clause.getConsumerMatchers()
98 .getEndpointIdentificationConstraints());
99 ConditionSet provCSet = buildProvConditionSet(clause);
100 addConditionSet(pkey, provCSet, egConditions);
101 EndpointConstraint provEpConstraint = new EndpointConstraint(provCSet,
102 clause.getProviderMatchers() == null ? null : clause.getProviderMatchers()
103 .getEndpointIdentificationConstraints());
104 List<Subject> clauseSubjects = subjectMap.get(consEpConstraint, provEpConstraint);
105 if (clauseSubjects == null) {
106 clauseSubjects = new ArrayList<>();
107 subjectMap.put(consEpConstraint, provEpConstraint, clauseSubjects);
109 for (SubjectName sn : clause.getSubjectRefs()) {
110 Subject s = subjects.get(sn);
112 clauseSubjects.add(s);
117 policy.put(ckey, pkey,
118 resolvePolicy(match.contractTenant,
128 private static boolean clauseMatchesByGroupReqAndCapConstraints(Clause clause, ContractMatch match) {
129 if (clause.getConsumerMatchers() != null) {
130 GroupIdentificationConstraints groupIdentificationConstraintsConsumer = clause.getConsumerMatchers()
131 .getGroupIdentificationConstraints();
132 if (groupIdentificationConstraintsConsumer instanceof GroupRequirementConstraintCase) {
133 List<RequirementMatcher> reqMatchers = ((GroupRequirementConstraintCase) groupIdentificationConstraintsConsumer)
134 .getRequirementMatcher();
135 if (reqMatchers != null) {
136 for (RequirementMatcher reqMatcher : reqMatchers) {
137 if (!MatcherUtils.applyReqMatcher(reqMatcher,
138 match.consumerRelator)) {
145 if (clause.getProviderMatchers() != null) {
146 org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.GroupIdentificationConstraints groupIdentificationConstraintsProvider = clause
147 .getProviderMatchers().getGroupIdentificationConstraints();
148 if (groupIdentificationConstraintsProvider instanceof GroupCapabilityConstraintCase) {
149 List<CapabilityMatcher> capMatchers = ((GroupCapabilityConstraintCase) groupIdentificationConstraintsProvider)
150 .getCapabilityMatcher();
152 if (capMatchers != null) {
153 for (CapabilityMatcher capMatcher : capMatchers) {
154 if (!MatcherUtils.applyCapMatcher(capMatcher,
155 match.providerRelator)) {
165 private static void addConditionSet(EgKey eg, ConditionSet cs,
166 Map<EgKey, Set<ConditionSet>> egConditions) {
167 if (egConditions == null)
169 Set<ConditionSet> cset = egConditions.get(eg);
171 egConditions.put(eg, cset = new HashSet<>());
176 private static ConditionSet buildConsConditionSet(Clause clause) {
177 if (clause.getConsumerMatchers() != null) {
178 List<ConditionMatcher> condMatchers =
179 clause.getConsumerMatchers().getConditionMatcher();
180 return buildConditionSet(condMatchers);
182 return ConditionSet.EMPTY;
185 private static ConditionSet buildProvConditionSet(Clause clause) {
186 if (clause.getProviderMatchers() != null) {
187 List<ConditionMatcher> condMatchers =
188 clause.getProviderMatchers().getConditionMatcher();
189 return buildConditionSet(condMatchers);
191 return ConditionSet.EMPTY;
194 private static ConditionSet buildConditionSet(List<ConditionMatcher> condMatchers) {
195 if (condMatchers == null)
196 return ConditionSet.EMPTY;
198 ImmutableSet.Builder<ConditionName> allb = ImmutableSet.builder();
199 ImmutableSet.Builder<ConditionName> noneb = ImmutableSet.builder();
200 ImmutableSet.Builder<Set<ConditionName>> anyb =
201 ImmutableSet.builder();
202 for (ConditionMatcher condMatcher : condMatchers) {
203 if (condMatcher.getCondition() == null)
205 MatchType type = condMatcher.getMatchType();
207 type = MatchType.All;
208 if (type.equals(MatchType.Any)) {
209 ImmutableSet.Builder<ConditionName> a =
210 ImmutableSet.builder();
211 for (Condition c : condMatcher.getCondition()) {
216 for (Condition c : condMatcher.getCondition()) {
221 noneb.add(c.getName());
225 allb.add(c.getName());
231 return new ConditionSet(allb.build(), noneb.build(), anyb.build());
234 private static Policy resolvePolicy(Tenant contractTenant,
237 Table<EndpointConstraint, EndpointConstraint,
238 List<Subject>> subjectMap) {
239 Table<EndpointConstraint, EndpointConstraint, List<RuleGroup>> ruleMap =
240 HashBasedTable.create();
242 ruleMap.putAll(merge.getRuleMap());
244 for (Cell<EndpointConstraint, EndpointConstraint, List<Subject>> entry : subjectMap.cellSet()) {
245 List<RuleGroup> rules = new ArrayList<>();
246 EndpointConstraint consEpConstraint = entry.getRowKey();
247 EndpointConstraint provEpConstraint = entry.getColumnKey();
248 List<RuleGroup> oldrules = ruleMap.get(consEpConstraint, provEpConstraint);
249 if (oldrules != null) {
250 rules.addAll(oldrules);
252 for (Subject s : entry.getValue()) {
253 if (s.getRule() == null)
256 RuleGroup rg = new RuleGroup(s.getRule(), s.getOrder(),
257 contractTenant, contract,
261 Collections.sort(rules);
262 ruleMap.put(consEpConstraint, provEpConstraint, Collections.unmodifiableList(rules));
264 return new Policy(ruleMap);