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.renderer.ofoverlay.endpoint;
11 import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ConcurrentMap;
23 import java.util.concurrent.CopyOnWriteArrayList;
24 import java.util.concurrent.ScheduledExecutorService;
26 import javax.annotation.Nullable;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
30 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
31 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
34 import org.opendaylight.groupbasedpolicy.dto.EgKey;
35 import org.opendaylight.groupbasedpolicy.dto.EpKey;
36 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
37 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointListener;
38 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.arp.ArpTasker;
39 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
40 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.statistics.OFStatisticsManager;
41 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
42 import org.opendaylight.groupbasedpolicy.util.IidFactory;
43 import org.opendaylight.groupbasedpolicy.util.SetUtils;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointFields;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayL3Context;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
68 import org.opendaylight.yangtools.concepts.ListenerRegistration;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
72 import com.google.common.base.Function;
73 import com.google.common.base.Optional;
74 import com.google.common.base.Preconditions;
75 import com.google.common.base.Predicate;
76 import com.google.common.collect.Collections2;
77 import com.google.common.collect.ImmutableList;
78 import com.google.common.collect.ImmutableSet;
79 import com.google.common.collect.Sets;
82 * Keep track of endpoints on the system. Maintain an index of endpoints and
83 * their locations for rendering. The endpoint manager will maintain
84 * appropriate indexes only for switches that are attached to the current
86 * In order to render the policy, we need to be able to efficiently enumerate
87 * all endpoints on a particular switch and also all the switches containing
88 * each particular endpoint group
90 public class EndpointManager implements AutoCloseable {
92 private static final Logger LOG = LoggerFactory.getLogger(EndpointManager.class);
93 private final EndpointManagerListener endpointListener;
94 private final OfOverlayContextListener ofOverlayContextListener;
95 private final OfOverlayL3ContextListener ofOverlayL3ContextListener;
96 private final ConcurrentMap<EpKey, Endpoint> endpoints = new ConcurrentHashMap<>();
97 private final ConcurrentMap<EpKey, Endpoint> externalEndpointsWithoutLocation = new ConcurrentHashMap<>();
98 private final ConcurrentMap<NodeId, ConcurrentMap<EgKey, Set<EpKey>>> endpointsByGroupByNode =
99 new ConcurrentHashMap<>();
100 private final ConcurrentMap<NodeId, Set<EpKey>> endpointsByNode = new ConcurrentHashMap<>();
101 private final ConcurrentMap<EgKey, Set<EpKey>> endpointsByGroup = new ConcurrentHashMap<>();
102 private final ScheduledExecutorService executor;
103 private final DataBroker dataProvider;
104 private final ArpTasker arpTasker;
105 private final ListenerRegistration<ArpTasker> notificationListenerRegistration;
106 private List<EndpointListener> listeners = new CopyOnWriteArrayList<>();
107 private Function<EpKey, Endpoint> indexTransform = new Function<EpKey, Endpoint>() {
110 public Endpoint apply(EpKey input) {
111 return endpoints.get(input);
115 public EndpointManager(DataBroker dataProvider, RpcProviderRegistry rpcRegistry,
116 NotificationService notificationService, ScheduledExecutorService executor, SwitchManager switchManager) {
117 this.executor = executor;
118 this.dataProvider = dataProvider;
119 if (rpcRegistry != null) {
120 if (notificationService != null && dataProvider != null) {
121 this.arpTasker = new ArpTasker(rpcRegistry, dataProvider);
122 notificationListenerRegistration = notificationService.registerNotificationListener(arpTasker);
124 LOG.info("Missing service {}", NotificationService.class.getSimpleName());
125 this.arpTasker = null;
126 this.notificationListenerRegistration = null;
129 LOG.warn("Missing service {}", RpcProviderRegistry.class.getSimpleName());
130 this.arpTasker = null;
131 this.notificationListenerRegistration = null;
133 if (dataProvider != null) {
134 endpointListener = new EndpointManagerListener(this.dataProvider, this);
135 ofOverlayContextListener = new OfOverlayContextListener(dataProvider, switchManager);
136 ofOverlayL3ContextListener = new OfOverlayL3ContextListener(dataProvider, switchManager);
138 endpointListener = null;
139 ofOverlayContextListener = null;
140 ofOverlayL3ContextListener = null;
142 LOG.debug("Initialized OFOverlay endpoint manager");
146 * Add a {@link EndpointListener} to get notifications of switch events
148 * @param listener - the {@link EndpointListener} to add
150 public void registerListener(EndpointListener listener) {
151 listeners.add(listener);
155 * Get a collection of endpoints attached to a particular switch
157 * @param nodeId - the nodeId of the switch to get endpoints for
158 * @return a collection of {@link Endpoint} objects.
160 public synchronized Set<EgKey> getGroupsForNode(NodeId nodeId) {
161 Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(nodeId);
163 return Collections.emptySet();
164 return ImmutableSet.copyOf(nodeEps.keySet());
168 * Get the set of nodes
170 * @param egKey - the egKey of the endpoint group to get nodes for
171 * @return a collection of {@link NodeId} objects.
173 public synchronized Set<NodeId> getNodesForGroup(final EgKey egKey) {
174 return ImmutableSet.copyOf(Sets.filter(endpointsByGroupByNode.keySet(), new Predicate<NodeId>() {
177 public boolean apply(NodeId input) {
178 Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(input);
179 return (nodeEps != null && nodeEps.containsKey(egKey));
186 * Get the endpoints in a particular group on a particular node
188 * @param nodeId - the node ID to look up
189 * @param eg - the group to look up
190 * @return the endpoints
192 public synchronized Collection<Endpoint> getEndpointsForNode(NodeId nodeId, EgKey eg) {
193 // TODO: alagalah Create method findEndpointsByNode() that uses
196 Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(nodeId);
198 return Collections.emptyList();
199 Collection<EpKey> ebn = nodeEps.get(eg);
201 return Collections.emptyList();
202 return ImmutableList.copyOf(Collections2.transform(ebn, indexTransform));
206 * Get the endpoints on a particular node
208 * @param nodeId - the node ID to look up
209 * @return the endpoints
211 public synchronized Collection<Endpoint> getEndpointsForNode(final NodeId nodeId) {
212 // TODO: alagalah Create method findEndpointsByNode() that uses
213 // data store. See commented code below.
215 Collection<EpKey> ebn = endpointsByNode.get(nodeId);
217 return Collections.emptyList();
218 return ImmutableList.copyOf(Collections2.transform(ebn, indexTransform));
222 * Get the endpoint object for the given key
224 * @param epKey - the key
225 * @return the {@link Endpoint} corresponding to the key
227 public Endpoint getEndpoint(EpKey epKey) {
228 return endpoints.get(epKey);
232 * Get a collection of endpoints in a particular endpoint group
234 * @param eg - Endpoint group key (contains endpoint group and tenant ID)
235 * @return a collection of {@link Endpoint} objects.
237 public synchronized Collection<Endpoint> getEndpointsForGroup(EgKey eg) {
238 Collection<EpKey> ebg = endpointsByGroup.get(eg);
240 return Collections.emptyList();
241 return ImmutableList.copyOf(Collections2.transform(ebg, indexTransform));
245 * Return set of external endpoints without location belonging to a particular endpoint group
247 * @param eg - Endpoint group key (contains endpoint group and tenant ID)
248 * @return a collection of {@link Endpoint} objects.
250 public synchronized Collection<Endpoint> getExtEpsNoLocForGroup(final EgKey eg) {
253 .copyOf(Collections2.filter(externalEndpointsWithoutLocation.values(), new Predicate<Endpoint>() {
256 public boolean apply(Endpoint input) {
257 Set<EndpointGroupId> epgIds = new HashSet<>();
258 if (input.getEndpointGroup() != null) {
259 epgIds.add(input.getEndpointGroup());
261 if (input.getEndpointGroups() != null) {
262 epgIds.addAll(input.getEndpointGroups());
264 if (epgIds.isEmpty()) {
265 LOG.error("No EPGs for {}. This is not a valid Endpoint.", input.getKey());
268 return (epgIds.contains(eg.getEgId()));
275 * Character of input parameters will determine action - create, update or delete L3Endpoint
277 * @param oldL3Ep the old L3 endpoint
278 * @param newL3Ep the new L3 endpoint
280 protected synchronized void processL3Endpoint(EndpointL3 oldL3Ep, EndpointL3 newL3Ep) {
282 // create L3 endpoint
283 if (oldL3Ep == null && newL3Ep != null) {
284 createL3Endpoint(newL3Ep);
285 OFStatisticsManager.addL3Endpoint(newL3Ep);
288 // update L3 endpoint
289 if (oldL3Ep != null && newL3Ep != null) {
290 updateL3Endpoint(newL3Ep);
293 // remove L3 endpoint
294 if (oldL3Ep != null && newL3Ep == null) {
295 OFStatisticsManager.removeL3Endpoint(oldL3Ep);
296 removeL3Endpoint(oldL3Ep);
301 * Character of input parameters will determine action - create, update or delete Endpoint
303 * @param oldEp - oldEp the new endpoint
304 * @param newEp - newEp the new endpoint
306 protected synchronized void processEndpoint(Endpoint oldEp, Endpoint newEp) {
307 NodeId oldLoc = getLocation(oldEp);
308 NodeId newLoc = getLocation(newEp);
309 EpKey oldEpKey = getEpKey(oldEp);
310 EpKey newEpKey = getEpKey(newEp);
311 TenantId tenantId = (newEp == null) ? null : newEp.getTenant();
313 Set<EndpointGroupId> oldEpgIds = getEndpointGroupsFromEndpoint(oldEp);
314 Set<EndpointGroupId> newEpgIds = getEndpointGroupsFromEndpoint(newEp);
316 boolean notifyOldLoc = false;
317 boolean notifyNewLoc = false;
318 boolean notifyOldEg = false;
319 boolean notifyNewEg = false;
322 if (oldEp == null && newEp != null) {
323 if (newLoc != null) {
324 createEndpoint(newLoc, newEpKey, newEpgIds, tenantId);
325 endpoints.put(newEpKey, newEp);
326 notifyEndpointUpdated(newEpKey);
330 externalEndpointsWithoutLocation.put(newEpKey, newEp);
335 else if (oldEp != null && newEp != null && oldEpKey != null && newEpKey != null) {
336 // endpoint is not external anymore
337 if (newLoc != null && oldLoc == null) {
338 createEndpoint(newLoc, newEpKey, newEpgIds, tenantId);
339 externalEndpointsWithoutLocation.remove(oldEpKey);
340 endpoints.put(newEpKey, newEp);
341 notifyEndpointUpdated(newEpKey);
345 // endpoint changed to external
346 else if (newLoc == null && oldLoc != null) {
347 removeEndpoint(oldEp, oldLoc, oldEpKey, oldEpgIds);
348 externalEndpointsWithoutLocation.put(newEpKey, newEp);
349 endpoints.remove(oldEpKey);
350 notifyEndpointUpdated(oldEpKey);
353 // endpoint might have changed location, EPGs or it's properties
354 } else if (newLoc != null && oldLoc != null) {
355 // endpoit changed location
356 if (!(oldLoc.getValue().equals(newLoc.getValue()))) {
360 // endpoint changed EPGs
361 if (!oldEpgIds.equals(newEpgIds)) {
365 removeEndpoint(oldEp, oldLoc, oldEpKey, oldEpgIds);
366 createEndpoint(newLoc, newEpKey, newEpgIds, tenantId);
367 notifyEndpointUpdated(newEpKey);
372 else if (oldEp != null && newEp == null) {
373 if (oldLoc != null) {
374 removeEndpoint(oldEp, oldLoc, oldEpKey, oldEpgIds);
375 endpoints.remove(oldEpKey);
376 notifyEndpointUpdated(oldEpKey);
380 externalEndpointsWithoutLocation.remove(oldEpKey);
386 notifyNodeEndpointUpdated(oldLoc, oldEpKey);
388 notifyNodeEndpointUpdated(newLoc, newEpKey);
390 for (EndpointGroupId oldEpgId : oldEpgIds) {
391 EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
392 notifyGroupEndpointUpdated(oldEgKey, oldEpKey);
395 for (EndpointGroupId newEpgId : newEpgIds) {
396 EgKey newEgKey = new EgKey(newEp.getTenant(), newEpgId);
397 notifyGroupEndpointUpdated(newEgKey, newEpKey);
401 private void createEndpoint(NodeId newLoc, EpKey newEpKey, Set<EndpointGroupId> newEpgIds, TenantId tenantId) {
402 // Update endpointsByNode
403 if (endpointsByNode.get(newLoc) == null) {
404 Set<EpKey> epsNode = new HashSet<>();
405 epsNode.add(newEpKey);
406 endpointsByNode.put(newLoc, epsNode);
407 SwitchManager.activatingSwitch(newLoc);
409 Set<EpKey> epsNode = endpointsByNode.get(newLoc);
410 epsNode.add(newEpKey);
413 // Update endpointsByGroupByNode and endpointsByGroup
414 for (EndpointGroupId newEpgId : newEpgIds) {
415 // endpointsByGroupByNode
416 EgKey newEgKey = new EgKey(tenantId, newEpgId);
417 Set<EpKey> eps = getEpNGSet(newLoc, newEgKey);
420 Set<EpKey> geps = endpointsByGroup.get(newEgKey);
422 geps = new HashSet<>();
425 endpointsByGroup.put(newEgKey, geps);
426 LOG.debug("Endpoint {} added to node {}", newEpKey, newLoc);
431 private void removeEndpoint(Endpoint oldEp, NodeId oldLoc, EpKey oldEpKey, Set<EndpointGroupId> oldEpgIds) {
432 // Update endpointsByNode
433 Set<EpKey> epsNode = endpointsByNode.get(oldLoc);
434 if (epsNode != null) {
435 epsNode.remove(oldEpKey);
436 if (epsNode.isEmpty()) {
437 endpointsByNode.remove(oldLoc);
438 SwitchManager.deactivatingSwitch(oldLoc);
442 // Update endpointsByGroupByNode and endpointsByGroup, get map of EPGs and their Endpoints
444 ConcurrentMap<EgKey, Set<EpKey>> map = endpointsByGroupByNode.get(oldLoc);
445 for (EndpointGroupId oldEpgId : oldEpgIds) {
446 // endpointsByGroupByNode
447 EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
448 Set<EpKey> eps = map.get(oldEgKey);
450 eps.remove(oldEpKey);
452 map.remove(oldEgKey, Collections.emptySet());
455 Set<EpKey> geps = endpointsByGroup.get(oldEgKey);
457 geps.remove(oldEpKey);
459 endpointsByGroup.remove(oldEgKey);
463 // If map is empty, no more EPGs on this node, remove node from map
465 endpointsByGroupByNode.remove(oldLoc);
469 private void createL3Endpoint(EndpointL3 newL3Ep) {
470 LOG.trace("Processing L3Endpoint {}", newL3Ep.getKey());
471 if (isValidL3Ep(newL3Ep)) {
472 if (newL3Ep.getMacAddress() == null) {
473 if (newL3Ep.getNetworkContainment() != null) {
474 arpTasker.addMacForL3EpAndCreateEp(newL3Ep);
476 LOG.error("Cannot generate MacAddress for L3Endpoint {}. NetworkContainment is null.", newL3Ep);
480 if (newL3Ep.getL2Context() != null && newL3Ep.getMacAddress() != null) {
481 notifyEndpointUpdated(new EpKey(newL3Ep.getL2Context(), newL3Ep.getMacAddress()));
485 LOG.error("{} is not a valid L3 Endpoint", newL3Ep);
488 if (newL3Ep.getAugmentation(OfOverlayL3Context.class) == null) {
489 LOG.info("L3Endpoint created but no augmentation information");
493 private void updateL3Endpoint(EndpointL3 newL3Ep) {
494 LOG.trace("Updating L3 Endpoint {}");
495 notifyEndpointUpdated(new EpKey(newL3Ep.getL2Context(), newL3Ep.getMacAddress()));
496 if (newL3Ep.getAugmentation(OfOverlayL3Context.class) == null) {
497 LOG.info("L3Endpoint updated but no augmentation information");
501 private void removeL3Endpoint(EndpointL3 oldL3Ep) {
502 LOG.trace("Removing L3 Endpoint {}");
503 notifyEndpointUpdated(new EpKey(oldL3Ep.getL2Context(), oldL3Ep.getMacAddress()));
509 public void close() throws Exception {
510 if (endpointListener != null) {
511 endpointListener.close();
513 if (notificationListenerRegistration != null) {
514 notificationListenerRegistration.close();
516 if (ofOverlayContextListener != null) {
517 ofOverlayContextListener.close();
519 if (ofOverlayL3ContextListener != null) {
520 ofOverlayL3ContextListener.close();
524 private Set<EpKey> getEpNGSet(NodeId location, EgKey eg) {
525 ConcurrentMap<EgKey, Set<EpKey>> map = endpointsByGroupByNode.get(location);
527 map = new ConcurrentHashMap<>();
528 ConcurrentMap<EgKey, Set<EpKey>> old = endpointsByGroupByNode.putIfAbsent(location, map);
532 return SetUtils.getNestedSet(eg, map);
536 * An endpoint is external if its endpoint-group is external implicit group.
538 * @param ep an endpoint
539 * @param eigs external implicit groups
540 * @return {@code true} if the given endpoint has EPG representing external implicit group;
541 * {@code false} otherwise
542 * @throws NullPointerException if the given endpoint is {@code null}
543 * @throws IllegalArgumentException if the given endpoint does not contain any endpoint-group
545 public static boolean isExternal(Endpoint ep, @Nullable Collection<ExternalImplicitGroup> eigs) {
546 return !isInternal(ep, eigs);
550 * An endpoint is internal if none of its endpoint-groups is external implicit group.
552 * @param ep an endpoint
553 * @param eigs external implicit groups
554 * @return {@code true} if the given endpoint does not have EPG representing external implicit
556 * {@code false} otherwise
557 * @throws NullPointerException if the given endpoint is {@code null}
558 * @throws IllegalArgumentException if the given endpoint does not contain any endpoint-group
560 public static boolean isInternal(Endpoint ep, @Nullable Collection<ExternalImplicitGroup> eigs) {
561 Preconditions.checkNotNull(ep);
562 if (eigs == null || eigs.isEmpty()) {
565 Set<EndpointGroupId> epgs = getEpgs(ep);
566 Preconditions.checkArgument(!epgs.isEmpty());
567 for (EndpointGroupId epg : epgs) {
568 for (ExternalImplicitGroup eig : eigs) {
569 if (epg.equals(eig.getId())) {
577 private static Set<EndpointGroupId> getEpgs(EndpointFields ep) {
578 EndpointGroupId epgId = ep.getEndpointGroup();
579 List<EndpointGroupId> epgsId = ep.getEndpointGroups();
580 Set<EndpointGroupId> result = new HashSet<>();
584 if (epgsId != null) {
585 result.addAll(epgsId);
591 * Get the endpoints container from data store.
592 * Note: There are maps maintained by listener when higher performance is required.
595 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints}
597 protected Endpoints getEndpointsFromDataStore() {
599 * XXX: alagalah I wanted to avoid adding another Map. Due to not being able to
600 * get to the granularity of the L3PrefixEndpoint List within the Endpoints container
601 * in the data store, we have to pull all the Endpoints. If this causes performance issues
602 * we may have to revisit a Map in updateEndpoint but note, this Endpoint doesn't have a
604 * and hence we would have to process it outside the null location check.
606 if (dataProvider == null) {
607 LOG.error("Null DataProvider in EndpointManager getEndpointsL3Prefix");
610 ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
611 Optional<Endpoints> endpoints =
612 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
613 IidFactory.endpointsIidWildcard(), rTx);
614 if (!endpoints.isPresent()) {
615 LOG.warn("No Endpoints present in data store.");
618 return endpoints.get();
622 * Return all L3Endpoints from data store.
625 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3}
626 * @return {@link Collection} of the {@link EndpointL3}.
627 * Empty {@link Collection} if no {@link EndpointL3} is found.
629 protected Collection<EndpointL3> getL3Endpoints() {
630 Endpoints endpoints = getEndpointsFromDataStore();
631 if (endpoints == null || endpoints.getEndpointL3() == null) {
632 LOG.warn("No L3 Endpoints present in data store.");
635 return endpoints.getEndpointL3();
639 * Return all L3Prefix Endpoints from data store.
642 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix}
644 private Collection<EndpointL3Prefix> getEndpointsL3Prefix() {
645 Endpoints endpoints = getEndpointsFromDataStore();
646 if (endpoints == null || endpoints.getEndpointL3Prefix() == null) {
647 LOG.warn("No L3 Prefix Endpoints present in data store.");
650 return endpoints.getEndpointL3Prefix();
654 * Return all L3Prefix Endpoints which come under particular tenant
656 * @param tenantId - the
657 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId}
660 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix}
662 public Collection<EndpointL3Prefix> getEndpointsL3PrefixForTenant(final TenantId tenantId) {
663 Collection<EndpointL3Prefix> l3PrefixEndpoints = getEndpointsL3Prefix();
664 if (l3PrefixEndpoints == null) {
665 // Log message already generated in getEndpointsL3Prefix()
668 return ImmutableSet.copyOf(Collections2.filter(l3PrefixEndpoints, new Predicate<EndpointL3Prefix>() {
671 public boolean apply(EndpointL3Prefix input) {
672 return (input.getTenant().equals(tenantId));
679 * Return all L3Endpoints containing network and port address translation in augmentation
682 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3}
684 public Collection<EndpointL3> getL3EndpointsWithNat() {
685 Collection<EndpointL3> l3Endpoints = getL3Endpoints();
686 if (l3Endpoints == null) {
689 l3Endpoints = Collections2.filter(l3Endpoints, new Predicate<EndpointL3>() {
692 public boolean apply(EndpointL3 input) {
693 return !((input.getAugmentation(NatAddress.class) == null)
694 || (input.getAugmentation(NatAddress.class).getNatAddress() == null));
697 if (l3Endpoints == null) {
698 return Collections.emptySet();
700 return ImmutableSet.copyOf(l3Endpoints);
704 * Set the learning mode to the specified value
706 * @param learningMode - the learning mode to set
708 @SuppressWarnings({"UnusedParameters", "EmptyMethod"})
709 public void setLearningMode(OfOverlayConfig.LearningMode learningMode) {
714 * Get the effective list of conditions that apply to a particular endpoint.
715 * This could include additional conditions over the condition labels
716 * directly represented in the endpoint object
719 * @param endpoint - the
720 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint}
722 * @return the list of
723 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName}
725 public List<ConditionName> getConditionsForEndpoint(Endpoint endpoint) {
726 // TODO Be alagalah From Helium: consider group conditions as well. Also
728 // endpoint updated if the endpoint group conditions change
729 if (endpoint.getCondition() != null)
730 return endpoint.getCondition();
732 return Collections.emptyList();
735 private void notifyEndpointUpdated(EpKey epKey) {
736 for (EndpointListener l : listeners) {
737 l.endpointUpdated(epKey);
741 private void notifyNodeEndpointUpdated(NodeId nodeId, EpKey epKey) {
742 for (EndpointListener l : listeners) {
743 l.nodeEndpointUpdated(nodeId, epKey);
747 private void notifyGroupEndpointUpdated(EgKey egKey, EpKey epKey) {
748 for (EndpointListener l : listeners) {
749 l.groupEndpointUpdated(egKey, epKey);
753 private boolean isValidEp(Endpoint endpoint) {
754 return (endpoint != null && endpoint.getTenant() != null
755 && (endpoint.getEndpointGroup() != null || endpoint.getEndpointGroups() != null)
756 && endpoint.getL2Context() != null && endpoint.getMacAddress() != null);
759 private boolean isValidL3Ep(EndpointL3 endpoint) {
760 return (endpoint != null && endpoint.getTenant() != null
761 && (endpoint.getEndpointGroup() != null || endpoint.getEndpointGroups() != null)
762 && endpoint.getL3Context() != null && endpoint.getIpAddress() != null);
765 private NodeId getLocation(Endpoint endpoint) {
766 if (isValidEp(endpoint)) {
767 OfOverlayContext context = endpoint.getAugmentation(OfOverlayContext.class);
769 return context.getNodeId();
774 private EpKey getEpKey(Endpoint endpoint) {
775 if (isValidEp(endpoint))
776 return new EpKey(endpoint.getL2Context(), endpoint.getMacAddress());
780 public Set<EgKey> getEgKeysForEndpoint(Endpoint ep) {
781 Set<EgKey> egKeys = new HashSet<>();
783 if (ep.getEndpointGroup() != null) {
784 egKeys.add(new EgKey(ep.getTenant(), ep.getEndpointGroup()));
786 if (ep.getEndpointGroups() != null) {
787 for (EndpointGroupId epgId : ep.getEndpointGroups()) {
788 egKeys.add(new EgKey(ep.getTenant(), epgId));
794 private Set<EndpointGroupId> getEndpointGroupsFromEndpoint(Endpoint ep) {
796 return new HashSet<>();
797 Set<EndpointGroupId> epgIds = new HashSet<>();
798 if (ep.getEndpointGroups() != null) {
799 epgIds.addAll(ep.getEndpointGroups());
801 if (ep.getEndpointGroup() != null) {
802 epgIds.add(ep.getEndpointGroup());
807 protected Map<EndpointKey, EndpointL3> getL3EpWithNatByL2Key() {
808 Map<EndpointKey, EndpointL3> l3EpByL2EpKey = new HashMap<>();
810 Collection<EndpointL3> l3Eps = getL3EndpointsWithNat();
812 l3EpByL2EpKey = Collections.emptyMap();
813 return l3EpByL2EpKey;
815 for (EndpointL3 l3Ep : l3Eps) {
816 if (l3Ep.getL2Context() != null && l3Ep.getMacAddress() != null) {
817 EndpointKey epKey = new EndpointKey(l3Ep.getL2Context(), l3Ep.getMacAddress());
818 l3EpByL2EpKey.put(epKey, l3Ep);
821 if (l3EpByL2EpKey.isEmpty()) {
822 l3EpByL2EpKey = Collections.emptyMap();
824 return l3EpByL2EpKey;
827 public EgKey getEgKey(Endpoint endpoint) {
828 if (!isValidEp(endpoint))
830 return new EgKey(endpoint.getTenant(), endpoint.getEndpointGroup());