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.Collections;
13 import java.util.HashMap;
14 import java.util.HashSet;
18 import javax.annotation.concurrent.Immutable;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.NetworkDomain;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Policy;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.SubjectFeatureInstances;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
41 import com.google.common.base.Function;
42 import com.google.common.collect.Collections2;
43 import com.google.common.collect.ImmutableSet;
46 * Wrap some convenient indexes around a {@link Tenant} object
50 public class IndexedTenant {
51 private final Tenant tenant;
52 private final int hashCode;
54 private final Map<EndpointGroupId, EndpointGroup> endpointGroups =
56 private final Map<ContractId, Contract> contracts =
58 private final Map<String, NetworkDomain> networkDomains =
60 private final Map<ClassifierName, ClassifierInstance> classifiers =
62 private final Map<ActionName, ActionInstance> actions =
64 private final Map<String, Set<SubnetId>> subnetMap = new HashMap<>();
65 private Set<ExternalImplicitGroup> externalImplicitGroups = Collections.emptySet();
67 public IndexedTenant(Tenant tenant) {
69 this.hashCode = tenant.hashCode();
70 if (tenant.getPolicy() != null) {
71 processPolicy(tenant.getPolicy());
73 if (tenant.getForwardingContext() != null) {
74 processForwardingContext(tenant.getForwardingContext());
78 private void processPolicy(Policy policy) {
79 if (policy.getEndpointGroup() != null) {
80 for (EndpointGroup eg : policy.getEndpointGroup()) {
81 endpointGroups.put(eg.getId(), eg);
84 if (policy.getExternalImplicitGroup() != null) {
85 externalImplicitGroups = ImmutableSet.copyOf(policy.getExternalImplicitGroup());
87 if (policy.getContract() != null) {
88 for (Contract c : policy.getContract()) {
89 contracts.put(c.getId(), c);
92 if (policy.getSubjectFeatureInstances() != null) {
93 SubjectFeatureInstances sfi = policy.getSubjectFeatureInstances();
94 if (sfi.getClassifierInstance() != null) {
95 for (ClassifierInstance ci : sfi.getClassifierInstance()) {
96 classifiers.put(ci.getName(), ci);
99 if (sfi.getActionInstance() != null) {
100 for (ActionInstance action : sfi.getActionInstance()) {
101 actions.put(action.getName(), action);
107 private void processForwardingContext(ForwardingContext fwCtx) {
108 if (fwCtx.getL3Context() != null) {
109 for (L3Context c : fwCtx.getL3Context()) {
110 networkDomains.put(c.getId().getValue(), c);
113 if (fwCtx.getL2BridgeDomain() != null) {
114 for (L2BridgeDomain c : fwCtx.getL2BridgeDomain()) {
115 networkDomains.put(c.getId().getValue(), c);
118 if (fwCtx.getL2FloodDomain() != null) {
119 for (L2FloodDomain c : fwCtx.getL2FloodDomain()) {
120 networkDomains.put(c.getId().getValue(), c);
123 if (fwCtx.getSubnet() != null) {
124 for (Subnet s : fwCtx.getSubnet()) {
125 networkDomains.put(s.getId().getValue(), s);
126 Set<SubnetId> sset = subnetMap.get(s.getParent().getValue());
128 subnetMap.put(s.getParent().getValue(), sset = new HashSet<SubnetId>());
136 * Get the underlying tenant object
137 * @return the {@link Tenant}
139 public Tenant getTenant() {
144 * Gets all external implicit groups in the tenant
145 * @return immutable set of EIGs
147 public Set<ExternalImplicitGroup> getExternalImplicitGroups() {
148 return externalImplicitGroups;
152 * Look up the network domain specified
153 * @param id the {@link NetworkDomainId}
154 * @return the {@link NetworkDomain} if it exists, or <code>null</code>
157 public NetworkDomain getNetworkDomain(NetworkDomainId id) {
158 return networkDomains.get(id.getValue());
162 * Look up the endpoint group specified
163 * @param id the {@link EndpointGroupId}
164 * @return the {@link EndpointGroup} if it exists, or <code>null</code>
167 public EndpointGroup getEndpointGroup(EndpointGroupId id) {
168 return endpointGroups.get(id);
172 * Look up the contract specified
173 * @param id the {@link ContractId}
174 * @return the {@link Contract} if it exists, or <code>null</code>
177 public Contract getContract(ContractId id) {
178 return contracts.get(id);
182 * Look up the classifier instance specified
183 * @param name the {@link ClassifierName}
184 * @return the {@link ClassifierInstance} if it exists, or <code>null</code>
187 public ClassifierInstance getClassifier(ClassifierName name) {
188 return classifiers.get(name);
192 * Look up the classifier instance specified
193 * @param name the {@link ActionName}
194 * @return the {@link ActionInstance} if it exists, or <code>null</code>
197 public ActionInstance getAction(ActionName name) {
198 return actions.get(name);
202 * Get the layer 3 context for the specified network domain by walking
204 * @param id the {@link NetworkDomainId} for the network domain
205 * @return the {@link L3Context} or <code>null</code> if it does not exist
207 public L3Context resolveL3Context(NetworkDomainId id) {
208 return resolveDomain(L3Context.class, id);
212 * Get the layer 2 bridge domain for the specified network domain by walking
214 * @param id the {@link NetworkDomainId} for the network domain
215 * @return the {@link L2BridgeDomain} or <code>null</code> if it does
218 public L2BridgeDomain resolveL2BridgeDomain(NetworkDomainId id) {
219 return resolveDomain(L2BridgeDomain.class, id);
223 * Get the layer 2 flood domain for the specified network domain by walking
225 * @param id the {@link NetworkDomainId} for the network domain
226 * @return the {@link L2FloodDomain} or <code>null</code> if it does
229 public L2FloodDomain resolveL2FloodDomain(NetworkDomainId id) {
230 return resolveDomain(L2FloodDomain.class, id);
234 * Resolve all subnets applicable to the given network domain ID
235 * @param id the {@link NetworkDomainId}
236 * @return the set of subnets. Cannot be null, but could be empty.
238 public Collection<Subnet> resolveSubnets(NetworkDomainId id) {
239 Set<SubnetId> sset = new HashSet<>();
240 HashSet<NetworkDomainId> visited = new HashSet<>();
242 if (visited.contains(id)) break;
244 Set<SubnetId> cursset = subnetMap.get(id.getValue());
246 sset.addAll(cursset);
247 NetworkDomain d = networkDomains.get(id.getValue());
248 if (d == null) break;
249 if (d instanceof Subnet) {
250 id = ((Subnet)d).getParent();
251 sset.add(((Subnet) d).getId());
253 else if (d instanceof L2BridgeDomain)
254 id = ((L2BridgeDomain)d).getParent();
255 else if (d instanceof L2FloodDomain)
256 id = ((L2FloodDomain)d).getParent();
260 return Collections2.transform(sset, new Function<SubnetId, Subnet>() {
262 public Subnet apply(SubnetId input) {
263 return (Subnet)networkDomains.get(input.getValue());
273 public int hashCode() {
278 public boolean equals(Object obj) {
283 if (getClass() != obj.getClass())
285 IndexedTenant other = (IndexedTenant) obj;
286 if (tenant == null) {
287 if (other.tenant != null)
289 } else if (!tenant.equals(other.tenant))
298 private <C extends NetworkDomain> C resolveDomain(Class<C> domainClass,
299 NetworkDomainId id) {
300 HashSet<NetworkDomainId> visited = new HashSet<>();
302 if (visited.contains(id)) return null;
304 NetworkDomain d = networkDomains.get(id.getValue());
305 if (d == null) return null;
306 if (domainClass.isInstance(d)) return domainClass.cast(d);
307 if (d instanceof Subnet)
308 id = ((Subnet)d).getParent();
309 else if (d instanceof L2BridgeDomain)
310 id = ((L2BridgeDomain)d).getParent();
311 else if (d instanceof L2FloodDomain)
312 id = ((L2FloodDomain)d).getParent();