2 * Copyright (c) 2014 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.dto;
11 import java.util.Collection;
12 import java.util.HashMap;
13 import java.util.HashSet;
17 import javax.annotation.concurrent.Immutable;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.NetworkDomain;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstances;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
39 import com.google.common.base.Function;
40 import com.google.common.collect.Collections2;
43 * Wrap some convenient indexes around a {@link Tenant} object
47 public class IndexedTenant {
48 private final Tenant tenant;
49 private final int hashCode;
51 private final Map<EndpointGroupId, EndpointGroup> endpointGroups =
53 private final Map<ContractId, Contract> contracts =
55 private final Map<String, NetworkDomain> networkDomains =
57 private final Map<ClassifierName, ClassifierInstance> classifiers =
59 private final Map<ActionName, ActionInstance> actions =
61 private final Map<String, Set<SubnetId>> subnetMap = new HashMap<>();
63 public IndexedTenant(Tenant tenant) {
65 this.hashCode = tenant.hashCode();
66 if (tenant.getPolicy() != null) {
67 processPolicy(tenant.getPolicy());
69 if (tenant.getForwardingContext() != null) {
70 processForwardingContext(tenant.getForwardingContext());
74 private void processPolicy(Policy policy) {
75 if (policy.getEndpointGroup() != null) {
76 for (EndpointGroup eg : policy.getEndpointGroup()) {
77 endpointGroups.put(eg.getId(), eg);
80 if (policy.getContract() != null) {
81 for (Contract c : policy.getContract()) {
82 contracts.put(c.getId(), c);
85 if (policy.getSubjectFeatureInstances() != null) {
86 SubjectFeatureInstances sfi = policy.getSubjectFeatureInstances();
87 if (sfi.getClassifierInstance() != null) {
88 for (ClassifierInstance ci : sfi.getClassifierInstance()) {
89 classifiers.put(ci.getName(), ci);
92 if (sfi.getActionInstance() != null) {
93 for (ActionInstance action : sfi.getActionInstance()) {
94 actions.put(action.getName(), action);
100 private void processForwardingContext(ForwardingContext fwCtx) {
101 if (fwCtx.getL3Context() != null) {
102 for (L3Context c : fwCtx.getL3Context()) {
103 networkDomains.put(c.getId().getValue(), c);
106 if (fwCtx.getL2BridgeDomain() != null) {
107 for (L2BridgeDomain c : fwCtx.getL2BridgeDomain()) {
108 networkDomains.put(c.getId().getValue(), c);
111 if (fwCtx.getL2FloodDomain() != null) {
112 for (L2FloodDomain c : fwCtx.getL2FloodDomain()) {
113 networkDomains.put(c.getId().getValue(), c);
116 if (fwCtx.getSubnet() != null) {
117 for (Subnet s : fwCtx.getSubnet()) {
118 networkDomains.put(s.getId().getValue(), s);
119 Set<SubnetId> sset = subnetMap.get(s.getParent().getValue());
121 subnetMap.put(s.getParent().getValue(), sset = new HashSet<SubnetId>());
129 * Get the underlying tenant object
130 * @return the {@link Tenant}
132 public Tenant getTenant() {
137 * Look up the network domain specified
138 * @param id the {@link NetworkDomainId}
139 * @return the {@link NetworkDomain} if it exists, or <code>null</code>
142 public NetworkDomain getNetworkDomain(NetworkDomainId id) {
143 return networkDomains.get(id.getValue());
147 * Look up the endpoint group specified
148 * @param id the {@link EndpointGroupId}
149 * @return the {@link EndpointGroup} if it exists, or <code>null</code>
152 public EndpointGroup getEndpointGroup(EndpointGroupId id) {
153 return endpointGroups.get(id);
157 * Look up the contract specified
158 * @param id the {@link ContractId}
159 * @return the {@link Contract} if it exists, or <code>null</code>
162 public Contract getContract(ContractId id) {
163 return contracts.get(id);
167 * Look up the classifier instance specified
168 * @param name the {@link ClassifierName}
169 * @return the {@link ClassifierInstance} if it exists, or <code>null</code>
172 public ClassifierInstance getClassifier(ClassifierName name) {
173 return classifiers.get(name);
177 * Look up the classifier instance specified
178 * @param name the {@link ActionName}
179 * @return the {@link ActionInstance} if it exists, or <code>null</code>
182 public ActionInstance getAction(ActionName name) {
183 return actions.get(name);
187 * Get the layer 3 context for the specified network domain by walking
189 * @param id the {@link NetworkDomainId} for the network domain
190 * @return the {@link L3Context} or <code>null</code> if it does not exist
192 public L3Context resolveL3Context(NetworkDomainId id) {
193 return resolveDomain(L3Context.class, id);
197 * Get the layer 2 bridge domain for the specified network domain by walking
199 * @param id the {@link NetworkDomainId} for the network domain
200 * @return the {@link L2BridgeDomain} or <code>null</code> if it does
203 public L2BridgeDomain resolveL2BridgeDomain(NetworkDomainId id) {
204 return resolveDomain(L2BridgeDomain.class, id);
208 * Get the layer 2 flood domain for the specified network domain by walking
210 * @param id the {@link NetworkDomainId} for the network domain
211 * @return the {@link L2FloodDomain} or <code>null</code> if it does
214 public L2FloodDomain resolveL2FloodDomain(NetworkDomainId id) {
215 return resolveDomain(L2FloodDomain.class, id);
219 * Resolve all subnets applicable to the given network domain ID
220 * @param id the {@link NetworkDomainId}
221 * @return the set of subnets. Cannot be null, but could be empty.
223 public Collection<Subnet> resolveSubnets(NetworkDomainId id) {
224 Set<SubnetId> sset = new HashSet<>();
225 HashSet<NetworkDomainId> visited = new HashSet<>();
227 if (visited.contains(id)) break;
229 Set<SubnetId> cursset = subnetMap.get(id.getValue());
231 sset.addAll(cursset);
232 NetworkDomain d = networkDomains.get(id.getValue());
233 if (d == null) break;
234 if (d instanceof Subnet) {
235 id = ((Subnet)d).getParent();
236 sset.add(((Subnet) d).getId());
238 else if (d instanceof L2BridgeDomain)
239 id = ((L2BridgeDomain)d).getParent();
240 else if (d instanceof L2FloodDomain)
241 id = ((L2FloodDomain)d).getParent();
245 return Collections2.transform(sset, new Function<SubnetId, Subnet>() {
247 public Subnet apply(SubnetId input) {
248 return (Subnet)networkDomains.get(input.getValue());
258 public int hashCode() {
263 public boolean equals(Object obj) {
268 if (getClass() != obj.getClass())
270 IndexedTenant other = (IndexedTenant) obj;
271 if (tenant == null) {
272 if (other.tenant != null)
274 } else if (!tenant.equals(other.tenant))
283 private <C extends NetworkDomain> C resolveDomain(Class<C> domainClass,
284 NetworkDomainId id) {
285 HashSet<NetworkDomainId> visited = new HashSet<>();
287 if (visited.contains(id)) return null;
289 NetworkDomain d = networkDomains.get(id.getValue());
290 if (d == null) return null;
291 if (domainClass.isInstance(d)) return domainClass.cast(d);
292 if (d instanceof Subnet)
293 id = ((Subnet)d).getParent();
294 else if (d instanceof L2BridgeDomain)
295 id = ((L2BridgeDomain)d).getParent();
296 else if (d instanceof L2FloodDomain)
297 id = ((L2FloodDomain)d).getParent();