Bug 4724 added containers to tenant
[groupbasedpolicy.git] / groupbasedpolicy / src / main / java / org / opendaylight / groupbasedpolicy / util / ContractResolverUtils.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.util;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Set;
14
15 import javax.annotation.concurrent.Immutable;
16
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;
33
34 import com.google.common.collect.HashBasedTable;
35 import com.google.common.collect.Table;
36
37
38 class ContractResolverUtils {
39
40     private ContractResolverUtils() {
41         throw new UnsupportedOperationException("Cannot create an instance");
42     }
43
44     /**
45      * Choose the contracts that are in scope for each pair of endpoint groups,
46      * then perform subject selection for the pair
47      */
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();
51
52         for (IndexedTenant tenant : tenants) {
53             selectContracts(consumerMatches, contractMatches, tenant.getTenant());
54         }
55         return contractMatches;
56     }
57
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) {
64             return;
65         }
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());
70                 if (cms == null) {
71                     cms = new ArrayList<>();
72                     consumerMatches.put(tenant.getId(), ccm.contract.getId(), cms);
73                 }
74                 cms.add(ccm);
75             }
76         }
77
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);
89                 }
90
91                 egPairMatches.add(cm);
92             }
93         }
94     }
95
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) {
101             return matches;
102         }
103         if (consumer.getConsumerNamedSelector() != null) {
104             for (ConsumerNamedSelector cns : consumer.getConsumerNamedSelector()) {
105                 if (cns.getContract() == null) {
106                     continue;
107                 }
108                 for (ContractId contractId : cns.getContract()) {
109                     Contract contract =
110                             TenantUtils.findContract(tenant, contractId);
111                     if (contract == null) {
112                         continue;
113                     }
114                     matches.add(new ConsumerContractMatch(tenant, contract,
115                             tenant, consumer,
116                             cns));
117                 }
118             }
119         }
120         if (consumer.getConsumerTargetSelector() != null) {
121             for (ConsumerTargetSelector cts : consumer.getConsumerTargetSelector()) {
122                 for (Contract contract : policy.getContract()) {
123                     if (contract.getTarget() == null) {
124                         continue;
125                     }
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)) {
131                                     match = false;
132                                     break;
133                                 }
134                             }
135                         }
136                         if (match) {
137                             matches.add(new ConsumerContractMatch(tenant,
138                                     contract,
139                                     tenant,
140                                     consumer,
141                                     cts));
142                         }
143                     }
144                 }
145             }
146         }
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()) {
152         //
153         // }
154         // }
155         return matches;
156     }
157
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) {
163             return matches;
164         }
165         if (provider.getProviderNamedSelector() != null) {
166             for (ProviderNamedSelector pns : provider.getProviderNamedSelector()) {
167                 if (pns.getContract() == null) {
168                     continue;
169                 }
170                 for (ContractId contractId : pns.getContract()) {
171                     Contract c = TenantUtils.findContract(tenant, contractId);
172                     if (c == null)
173                         continue;
174                     List<ConsumerContractMatch> cMatches = consumerMatches.get(tenant.getId(), c.getId());
175                     amendContractMatches(matches, cMatches, tenant, provider, pns);
176                 }
177             }
178         }
179         if (provider.getProviderTargetSelector() != null) {
180             for (ProviderTargetSelector pts : provider.getProviderTargetSelector()) {
181                 for (Contract c : policy.getContract()) {
182                     if (c.getTarget() == null)
183                         continue;
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)) {
189                                     match = false;
190                                     break;
191                                 }
192                             }
193                         }
194                         if (match) {
195                             List<ConsumerContractMatch> cMatches = consumerMatches.get(tenant.getId(), c.getId());
196                             amendContractMatches(matches, cMatches, tenant, provider, pts);
197
198                         }
199                     }
200                 }
201             }
202         }
203         return matches;
204     }
205
206     private static void amendContractMatches(List<ContractMatch> matches,
207             List<ConsumerContractMatch> cMatches,
208             Tenant tenant, EndpointGroup provider,
209             ProviderSelectionRelator relator) {
210         if (cMatches == null) {
211             return;
212         }
213         for (ConsumerContractMatch cMatch : cMatches) {
214             matches.add(new ContractMatch(cMatch, tenant, provider, relator));
215         }
216     }
217
218     /**
219      * Represents a selected contract made by endpoint groups matching it using
220      * selection relators. This is the result of the contract selection phase.
221      *
222      * @author readams
223      */
224     @Immutable
225     static class ContractMatch extends ConsumerContractMatch {
226
227         /**
228          * The tenant ID of the provider endpoint group
229          */
230         final Tenant providerTenant;
231
232         /**
233          * The provider endpoint group
234          */
235         final EndpointGroup provider;
236
237         /**
238          * The provider selection relator that was used to match the contract
239          */
240         final ProviderSelectionRelator providerRelator;
241
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;
249         }
250     }
251
252     @Immutable
253     static class ConsumerContractMatch {
254
255         /**
256          * The tenant of the matching contract
257          */
258         final Tenant contractTenant;
259
260         /**
261          * The matching contract
262          */
263         final Contract contract;
264
265         /**
266          * The tenant for the endpoint group
267          */
268         final Tenant consumerTenant;
269
270         /**
271          * The consumer endpoint group
272          */
273         final EndpointGroup consumer;
274
275         /**
276          * The consumer selection relator that was used to match the contract
277          */
278         final ConsumerSelectionRelator consumerRelator;
279
280         public ConsumerContractMatch(Tenant contractTenant, Contract contract, Tenant consumerTenant,
281                 EndpointGroup consumer, ConsumerSelectionRelator consumerRelator) {
282             super();
283             this.contractTenant = contractTenant;
284             this.contract = contract;
285             this.consumerTenant = consumerTenant;
286             this.consumer = consumer;
287             this.consumerRelator = consumerRelator;
288         }
289     }
290
291 }