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.List;
15 import javax.annotation.concurrent.Immutable;
17 import org.opendaylight.groupbasedpolicy.dto.EgKey;
18 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ConsumerSelectionRelator;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ProviderSelectionRelator;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.target.selector.QualityMatcher;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Target;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerTargetSelector;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderTargetSelector;
34 import com.google.common.collect.HashBasedTable;
35 import com.google.common.collect.Table;
38 class ContractResolverUtils {
40 private ContractResolverUtils() {
41 throw new UnsupportedOperationException("Cannot create an instance");
45 * Choose the contracts that are in scope for each pair of endpoint groups,
46 * then perform subject selection for the pair
48 static Table<EgKey, EgKey, List<ContractMatch>> selectContracts(Set<IndexedTenant> tenants) {
49 Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches = HashBasedTable.create();
50 Table<EgKey, EgKey, List<ContractMatch>> contractMatches = HashBasedTable.create();
52 for (IndexedTenant tenant : tenants) {
53 selectContracts(consumerMatches, contractMatches, tenant.getTenant());
55 return contractMatches;
58 static void selectContracts(Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches,
59 Table<EgKey, EgKey, List<ContractMatch>> contractMatches, Tenant tenant) {
60 // For each endpoint group, match consumer selectors
61 // against contracts to get a set of matching consumer selectors
62 Policy policy = tenant.getPolicy();
63 if (policy == null || policy.getEndpointGroup() == null) {
66 for (EndpointGroup group : policy.getEndpointGroup()) {
67 List<ConsumerContractMatch> r = matchConsumerContracts(tenant, group);
68 for (ConsumerContractMatch ccm : r) {
69 List<ConsumerContractMatch> cms = consumerMatches.get(tenant.getId(), ccm.contract.getId());
71 cms = new ArrayList<>();
72 consumerMatches.put(tenant.getId(), ccm.contract.getId(), cms);
78 // Match provider selectors, and check each match for a corresponding
79 // consumer selector match.
80 for (EndpointGroup group : policy.getEndpointGroup()) {
81 List<ContractMatch> matches = matchProviderContracts(tenant, group, consumerMatches);
82 for (ContractMatch cm : matches) {
83 EgKey consumerKey = new EgKey(cm.consumerTenant.getId(), cm.consumer.getId());
84 EgKey providerKey = new EgKey(cm.providerTenant.getId(), cm.provider.getId());
85 List<ContractMatch> egPairMatches = contractMatches.get(consumerKey, providerKey);
86 if (egPairMatches == null) {
87 egPairMatches = new ArrayList<>();
88 contractMatches.put(consumerKey, providerKey, egPairMatches);
91 egPairMatches.add(cm);
96 private static List<ConsumerContractMatch> matchConsumerContracts(Tenant tenant,
97 EndpointGroup consumer) {
98 List<ConsumerContractMatch> matches = new ArrayList<>();
99 Policy policy = tenant.getPolicy();
100 if (policy == null || policy.getContract() == null) {
103 if (consumer.getConsumerNamedSelector() != null) {
104 for (ConsumerNamedSelector cns : consumer.getConsumerNamedSelector()) {
105 if (cns.getContract() == null) {
108 for (ContractId contractId : cns.getContract()) {
110 TenantUtils.findContract(tenant, contractId);
111 if (contract == null) {
114 matches.add(new ConsumerContractMatch(tenant, contract,
120 if (consumer.getConsumerTargetSelector() != null) {
121 for (ConsumerTargetSelector cts : consumer.getConsumerTargetSelector()) {
122 for (Contract contract : policy.getContract()) {
123 if (contract.getTarget() == null) {
126 for (Target t : contract.getTarget()) {
127 boolean match = true;
128 if (cts.getQualityMatcher() != null) {
129 for (QualityMatcher m : cts.getQualityMatcher()) {
130 if (!MatcherUtils.applyQualityMatcher(m, t)) {
137 matches.add(new ConsumerContractMatch(tenant,
147 // TODO match selectors also against contract references
148 // for (ConsumerTargetSelector cts :
149 // consumer.getConsumerTargetSelector()) {
150 // if (tenant.getContractRef() == null) continue;
151 // for (ContractRef c : tenant.getContractRef()) {
158 private static List<ContractMatch> matchProviderContracts(Tenant tenant, EndpointGroup provider,
159 Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches) {
160 List<ContractMatch> matches = new ArrayList<>();
161 Policy policy = tenant.getPolicy();
162 if (policy == null || policy.getContract() == null) {
165 if (provider.getProviderNamedSelector() != null) {
166 for (ProviderNamedSelector pns : provider.getProviderNamedSelector()) {
167 if (pns.getContract() == null) {
170 for (ContractId contractId : pns.getContract()) {
171 Contract c = TenantUtils.findContract(tenant, contractId);
174 List<ConsumerContractMatch> cMatches = consumerMatches.get(tenant.getId(), c.getId());
175 amendContractMatches(matches, cMatches, tenant, provider, pns);
179 if (provider.getProviderTargetSelector() != null) {
180 for (ProviderTargetSelector pts : provider.getProviderTargetSelector()) {
181 for (Contract c : policy.getContract()) {
182 if (c.getTarget() == null)
184 for (Target t : c.getTarget()) {
185 boolean match = true;
186 if (pts.getQualityMatcher() != null) {
187 for (QualityMatcher m : pts.getQualityMatcher()) {
188 if (!MatcherUtils.applyQualityMatcher(m, t)) {
195 List<ConsumerContractMatch> cMatches = consumerMatches.get(tenant.getId(), c.getId());
196 amendContractMatches(matches, cMatches, tenant, provider, pts);
206 private static void amendContractMatches(List<ContractMatch> matches,
207 List<ConsumerContractMatch> cMatches,
208 Tenant tenant, EndpointGroup provider,
209 ProviderSelectionRelator relator) {
210 if (cMatches == null) {
213 for (ConsumerContractMatch cMatch : cMatches) {
214 matches.add(new ContractMatch(cMatch, tenant, provider, relator));
219 * Represents a selected contract made by endpoint groups matching it using
220 * selection relators. This is the result of the contract selection phase.
225 static class ContractMatch extends ConsumerContractMatch {
228 * The tenant ID of the provider endpoint group
230 final Tenant providerTenant;
233 * The provider endpoint group
235 final EndpointGroup provider;
238 * The provider selection relator that was used to match the contract
240 final ProviderSelectionRelator providerRelator;
242 public ContractMatch(ConsumerContractMatch consumerMatch, Tenant providerTenant, EndpointGroup provider,
243 ProviderSelectionRelator providerRelator) {
244 super(consumerMatch.contractTenant, consumerMatch.contract, consumerMatch.consumerTenant,
245 consumerMatch.consumer, consumerMatch.consumerRelator);
246 this.providerTenant = providerTenant;
247 this.provider = provider;
248 this.providerRelator = providerRelator;
253 static class ConsumerContractMatch {
256 * The tenant of the matching contract
258 final Tenant contractTenant;
261 * The matching contract
263 final Contract contract;
266 * The tenant for the endpoint group
268 final Tenant consumerTenant;
271 * The consumer endpoint group
273 final EndpointGroup consumer;
276 * The consumer selection relator that was used to match the contract
278 final ConsumerSelectionRelator consumerRelator;
280 public ConsumerContractMatch(Tenant contractTenant, Contract contract, Tenant consumerTenant,
281 EndpointGroup consumer, ConsumerSelectionRelator consumerRelator) {
283 this.contractTenant = contractTenant;
284 this.contract = contract;
285 this.consumerTenant = consumerTenant;
286 this.consumer = consumer;
287 this.consumerRelator = consumerRelator;