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.util.DataStoreHelper;
41 import org.opendaylight.groupbasedpolicy.util.IidFactory;
42 import org.opendaylight.groupbasedpolicy.util.SetUtils;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointFields;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayL3Context;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
66 import org.opendaylight.yangtools.concepts.ListenerRegistration;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
70 import com.google.common.base.Function;
71 import com.google.common.base.Optional;
72 import com.google.common.base.Preconditions;
73 import com.google.common.base.Predicate;
74 import com.google.common.collect.Collections2;
75 import com.google.common.collect.ImmutableList;
76 import com.google.common.collect.ImmutableSet;
77 import com.google.common.collect.Sets;
80 * Keep track of endpoints on the system. Maintain an index of endpoints and
81 * their locations for rendering. The endpoint manager will maintain
82 * appropriate indexes only for switches that are attached to the current
84 * In order to render the policy, we need to be able to efficiently enumerate
85 * all endpoints on a particular switch and also all the switches containing
86 * each particular endpoint group
88 public class EndpointManager implements AutoCloseable {
90 private static final Logger LOG = LoggerFactory.getLogger(EndpointManager.class);
91 private final EndpointManagerListener endpointListener;
92 private final ConcurrentHashMap<EpKey, Endpoint> endpoints = new ConcurrentHashMap<>();
93 private final ConcurrentHashMap<EpKey, Endpoint> externalEndpointsWithoutLocation = new ConcurrentHashMap<>();
94 private final ConcurrentHashMap<NodeId, ConcurrentMap<EgKey, Set<EpKey>>> endpointsByGroupByNode =
95 new ConcurrentHashMap<>();
96 private final ConcurrentHashMap<NodeId, Set<EpKey>> endpointsByNode = new ConcurrentHashMap<>();
97 private final ConcurrentHashMap<EgKey, Set<EpKey>> endpointsByGroup = new ConcurrentHashMap<>();
98 private final ScheduledExecutorService executor;
99 private final DataBroker dataProvider;
100 private final ArpTasker arpTasker;
101 private final ListenerRegistration<ArpTasker> notificationListenerRegistration;
102 private List<EndpointListener> listeners = new CopyOnWriteArrayList<>();
103 private Function<EpKey, Endpoint> indexTransform = new Function<EpKey, Endpoint>() {
106 public Endpoint apply(EpKey input) {
107 return endpoints.get(input);
111 public EndpointManager(DataBroker dataProvider, RpcProviderRegistry rpcRegistry,
112 NotificationService notificationService, ScheduledExecutorService executor, SwitchManager switchManager) {
113 this.executor = executor;
114 this.dataProvider = dataProvider;
115 if (rpcRegistry != null) {
116 if (notificationService != null && dataProvider != null) {
117 this.arpTasker = new ArpTasker(rpcRegistry, dataProvider);
118 notificationListenerRegistration = notificationService.registerNotificationListener(arpTasker);
120 LOG.info("Missing service {}", NotificationService.class.getSimpleName());
121 this.arpTasker = null;
122 this.notificationListenerRegistration = null;
125 LOG.warn("Missing service {}", RpcProviderRegistry.class.getSimpleName());
126 this.arpTasker = null;
127 this.notificationListenerRegistration = null;
129 if (dataProvider != null) {
130 endpointListener = new EndpointManagerListener(this.dataProvider, this);
132 endpointListener = null;
134 LOG.debug("Initialized OFOverlay endpoint manager");
138 * Add a {@link EndpointListener} to get notifications of switch events
140 * @param listener - the {@link EndpointListener} to add
142 public void registerListener(EndpointListener listener) {
143 listeners.add(listener);
147 * Get a collection of endpoints attached to a particular switch
149 * @param nodeId - the nodeId of the switch to get endpoints for
150 * @return a collection of {@link Endpoint} objects.
152 public synchronized Set<EgKey> getGroupsForNode(NodeId nodeId) {
153 Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(nodeId);
155 return Collections.emptySet();
156 return ImmutableSet.copyOf(nodeEps.keySet());
160 * Get the set of nodes
162 * @param egKey - the egKey of the endpoint group to get nodes for
163 * @return a collection of {@link NodeId} objects.
165 public synchronized Set<NodeId> getNodesForGroup(final EgKey egKey) {
166 return ImmutableSet.copyOf(Sets.filter(endpointsByGroupByNode.keySet(), new Predicate<NodeId>() {
169 public boolean apply(NodeId input) {
170 Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(input);
171 return (nodeEps != null && nodeEps.containsKey(egKey));
178 * Get the endpoints in a particular group on a particular node
180 * @param nodeId - the node ID to look up
181 * @param eg - the group to look up
182 * @return the endpoints
184 public synchronized Collection<Endpoint> getEndpointsForNode(NodeId nodeId, EgKey eg) {
185 // TODO: alagalah Create method findEndpointsByNode() that uses
188 Map<EgKey, Set<EpKey>> nodeEps = endpointsByGroupByNode.get(nodeId);
190 return Collections.emptyList();
191 Collection<EpKey> ebn = nodeEps.get(eg);
193 return Collections.emptyList();
194 return ImmutableList.copyOf(Collections2.transform(ebn, indexTransform));
198 * Get the endpoints on a particular node
200 * @param nodeId - the node ID to look up
201 * @return the endpoints
203 public synchronized Collection<Endpoint> getEndpointsForNode(final NodeId nodeId) {
204 // TODO: alagalah Create method findEndpointsByNode() that uses
205 // data store. See commented code below.
207 Collection<EpKey> ebn = endpointsByNode.get(nodeId);
209 return Collections.emptyList();
210 return ImmutableList.copyOf(Collections2.transform(ebn, indexTransform));
214 * Get the endpoint object for the given key
216 * @param epKey - the key
217 * @return the {@link Endpoint} corresponding to the key
219 public Endpoint getEndpoint(EpKey epKey) {
220 return endpoints.get(epKey);
224 * Get a collection of endpoints in a particular endpoint group
226 * @param eg - Endpoint group key (contains endpoint group and tenant ID)
227 * @return a collection of {@link Endpoint} objects.
229 public synchronized Collection<Endpoint> getEndpointsForGroup(EgKey eg) {
230 Collection<EpKey> ebg = endpointsByGroup.get(eg);
232 return Collections.emptyList();
233 return ImmutableList.copyOf(Collections2.transform(ebg, indexTransform));
237 * Return set of external endpoints without location belonging to a particular endpoint group
239 * @param eg - Endpoint group key (contains endpoint group and tenant ID)
240 * @return a collection of {@link Endpoint} objects.
242 public synchronized Collection<Endpoint> getExtEpsNoLocForGroup(final EgKey eg) {
245 .copyOf(Collections2.filter(externalEndpointsWithoutLocation.values(), new Predicate<Endpoint>() {
248 public boolean apply(Endpoint input) {
249 Set<EndpointGroupId> epgIds = new HashSet<>();
250 if (input.getEndpointGroup() != null) {
251 epgIds.add(input.getEndpointGroup());
253 if (input.getEndpointGroups() != null) {
254 epgIds.addAll(input.getEndpointGroups());
256 if (epgIds.isEmpty()) {
257 LOG.error("No EPGs for {}. This is not a valid Endpoint.", input.getKey());
260 return (epgIds.contains(eg.getEgId()));
267 * Character of input parameters will determine action - create, update or delete L3Endpoint
269 * @param oldL3Ep the old L3 endpoint
270 * @param newL3Ep the new L3 endpoint
272 protected synchronized void processL3Endpoint(EndpointL3 oldL3Ep, EndpointL3 newL3Ep) {
274 // create L3 endpoint
275 if (oldL3Ep == null && newL3Ep != null) {
276 createL3Endpoint(newL3Ep);
279 // update L3 endpoint
280 if (oldL3Ep != null && newL3Ep != null) {
281 updateL3Endpoint(newL3Ep);
284 // remove L3 endpoint
285 if (oldL3Ep != null && newL3Ep == null) {
286 removeL3Endpoint(oldL3Ep);
291 * Character of input parameters will determine action - create, update or delete Endpoint
293 * @param oldEp - oldEp the new endpoint
294 * @param newEp - newEp the new endpoint
296 protected synchronized void processEndpoint(Endpoint oldEp, Endpoint newEp) {
297 NodeId oldLoc = getLocation(oldEp);
298 NodeId newLoc = getLocation(newEp);
299 EpKey oldEpKey = getEpKey(oldEp);
300 EpKey newEpKey = getEpKey(newEp);
301 TenantId tenantId = (newEp == null) ? null : newEp.getTenant();
303 Set<EndpointGroupId> oldEpgIds = getEndpointGroupsFromEndpoint(oldEp);
304 Set<EndpointGroupId> newEpgIds = getEndpointGroupsFromEndpoint(newEp);
306 boolean notifyOldLoc = false;
307 boolean notifyNewLoc = false;
308 boolean notifyOldEg = false;
309 boolean notifyNewEg = false;
312 if (oldEp == null && newEp != null) {
313 if (newLoc != null) {
314 createEndpoint(newLoc, newEpKey, newEpgIds, tenantId);
315 endpoints.put(newEpKey, newEp);
316 notifyEndpointUpdated(newEpKey);
320 externalEndpointsWithoutLocation.put(newEpKey, newEp);
325 else if (oldEp != null && newEp != null && oldEpKey != null && newEpKey != null) {
326 // endpoint is not external anymore
327 if (newLoc != null && oldLoc == null) {
328 createEndpoint(newLoc, newEpKey, newEpgIds, tenantId);
329 externalEndpointsWithoutLocation.remove(oldEpKey);
330 endpoints.put(newEpKey, newEp);
331 notifyEndpointUpdated(newEpKey);
335 // endpoint changed to external
336 else if (newLoc == null && oldLoc != null) {
337 removeEndpoint(oldEp, oldLoc, oldEpKey, oldEpgIds);
338 externalEndpointsWithoutLocation.put(newEpKey, newEp);
339 endpoints.remove(oldEpKey);
340 notifyEndpointUpdated(oldEpKey);
343 // endpoint might have changed location, EPGs or it's properties
344 } else if (newLoc != null && oldLoc != null) {
345 // endpoit changed location
346 if (!(oldLoc.getValue().equals(newLoc.getValue()))) {
350 // endpoint changed EPGs
351 if (!oldEpgIds.equals(newEpgIds)) {
355 removeEndpoint(oldEp, oldLoc, oldEpKey, oldEpgIds);
356 createEndpoint(newLoc, newEpKey, newEpgIds, tenantId);
357 notifyEndpointUpdated(newEpKey);
362 else if (oldEp != null && newEp == null) {
363 if (oldLoc != null) {
364 removeEndpoint(oldEp, oldLoc, oldEpKey, oldEpgIds);
365 endpoints.remove(oldEpKey);
366 notifyEndpointUpdated(oldEpKey);
370 externalEndpointsWithoutLocation.remove(oldEpKey);
376 notifyNodeEndpointUpdated(oldLoc, oldEpKey);
378 notifyNodeEndpointUpdated(newLoc, newEpKey);
380 for (EndpointGroupId oldEpgId : oldEpgIds) {
381 EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
382 notifyGroupEndpointUpdated(oldEgKey, oldEpKey);
385 for (EndpointGroupId newEpgId : newEpgIds) {
386 EgKey newEgKey = new EgKey(newEp.getTenant(), newEpgId);
387 notifyGroupEndpointUpdated(newEgKey, newEpKey);
391 private void createEndpoint(NodeId newLoc, EpKey newEpKey, Set<EndpointGroupId> newEpgIds, TenantId tenantId) {
392 // Update endpointsByNode
393 if (endpointsByNode.get(newLoc) == null) {
394 Set<EpKey> epsNode = new HashSet<>();
395 epsNode.add(newEpKey);
396 endpointsByNode.put(newLoc, epsNode);
397 SwitchManager.activatingSwitch(newLoc);
399 Set<EpKey> epsNode = endpointsByNode.get(newLoc);
400 epsNode.add(newEpKey);
403 // Update endpointsByGroupByNode and endpointsByGroup
404 for (EndpointGroupId newEpgId : newEpgIds) {
405 // endpointsByGroupByNode
406 EgKey newEgKey = new EgKey(tenantId, newEpgId);
407 Set<EpKey> eps = getEpNGSet(newLoc, newEgKey);
410 Set<EpKey> geps = endpointsByGroup.get(newEgKey);
412 geps = new HashSet<>();
415 endpointsByGroup.put(newEgKey, geps);
416 LOG.debug("Endpoint {} added to node {}", newEpKey, newLoc);
421 private void removeEndpoint(Endpoint oldEp, NodeId oldLoc, EpKey oldEpKey, Set<EndpointGroupId> oldEpgIds) {
422 // Update endpointsByNode
423 Set<EpKey> epsNode = endpointsByNode.get(oldLoc);
424 if (epsNode != null) {
425 epsNode.remove(oldEpKey);
426 if (epsNode.isEmpty()) {
427 endpointsByNode.remove(oldLoc);
428 SwitchManager.deactivatingSwitch(oldLoc);
432 // Update endpointsByGroupByNode and endpointsByGroup, get map of EPGs and their Endpoints
434 ConcurrentMap<EgKey, Set<EpKey>> map = endpointsByGroupByNode.get(oldLoc);
435 for (EndpointGroupId oldEpgId : oldEpgIds) {
436 // endpointsByGroupByNode
437 EgKey oldEgKey = new EgKey(oldEp.getTenant(), oldEpgId);
438 Set<EpKey> eps = map.get(oldEgKey);
440 eps.remove(oldEpKey);
442 map.remove(oldEgKey, Collections.emptySet());
445 Set<EpKey> geps = endpointsByGroup.get(oldEgKey);
447 geps.remove(oldEpKey);
449 endpointsByGroup.remove(oldEgKey);
453 // If map is empty, no more EPGs on this node, remove node from map
455 endpointsByGroupByNode.remove(oldLoc);
459 private void createL3Endpoint(EndpointL3 newL3Ep) {
460 LOG.trace("Processing L3Endpoint {}", newL3Ep.getKey());
461 if (isValidL3Ep(newL3Ep)) {
462 if (newL3Ep.getMacAddress() == null) {
463 if (newL3Ep.getNetworkContainment() != null) {
464 arpTasker.addMacForL3EpAndCreateEp(newL3Ep);
466 LOG.error("Cannot generate MacAddress for L3Endpoint {}. NetworkContainment is null.", newL3Ep);
470 if (newL3Ep.getL2Context() != null && newL3Ep.getMacAddress() != null) {
471 notifyEndpointUpdated(new EpKey(newL3Ep.getL2Context(), newL3Ep.getMacAddress()));
475 LOG.error("{} is not a valid L3 Endpoint", newL3Ep);
478 if (newL3Ep.getAugmentation(OfOverlayL3Context.class) == null) {
479 LOG.info("L3Endpoint created but no augmentation information");
483 private void updateL3Endpoint(EndpointL3 newL3Ep) {
484 LOG.trace("Updating L3 Endpoint {}");
485 notifyEndpointUpdated(new EpKey(newL3Ep.getL2Context(), newL3Ep.getMacAddress()));
486 if (newL3Ep.getAugmentation(OfOverlayL3Context.class) == null) {
487 LOG.info("L3Endpoint updated but no augmentation information");
491 private void removeL3Endpoint(EndpointL3 oldL3Ep) {
492 LOG.trace("Removing L3 Endpoint {}");
493 notifyEndpointUpdated(new EpKey(oldL3Ep.getL2Context(), oldL3Ep.getMacAddress()));
499 public void close() throws Exception {
500 if (endpointListener != null)
501 endpointListener.close();
502 if (notificationListenerRegistration != null) {
503 notificationListenerRegistration.close();
507 private Set<EpKey> getEpNGSet(NodeId location, EgKey eg) {
508 ConcurrentMap<EgKey, Set<EpKey>> map = endpointsByGroupByNode.get(location);
510 map = new ConcurrentHashMap<>();
511 ConcurrentMap<EgKey, Set<EpKey>> old = endpointsByGroupByNode.putIfAbsent(location, map);
515 return SetUtils.getNestedSet(eg, map);
519 * An endpoint is external if its endpoint-group is external implicit group.
521 * @param ep an endpoint
522 * @param eigs external implicit groups
523 * @return {@code true} if the given endpoint has EPG representing external implicit group;
524 * {@code false} otherwise
525 * @throws NullPointerException if the given endpoint is {@code null}
526 * @throws IllegalArgumentException if the given endpoint does not contain any endpoint-group
528 public static boolean isExternal(Endpoint ep, @Nullable Collection<ExternalImplicitGroup> eigs) {
529 return !isInternal(ep, eigs);
533 * An endpoint is internal if none of its endpoint-groups is external implicit group.
535 * @param ep an endpoint
536 * @param eigs external implicit groups
537 * @return {@code true} if the given endpoint does not have EPG representing external implicit
539 * {@code false} otherwise
540 * @throws NullPointerException if the given endpoint is {@code null}
541 * @throws IllegalArgumentException if the given endpoint does not contain any endpoint-group
543 public static boolean isInternal(Endpoint ep, @Nullable Collection<ExternalImplicitGroup> eigs) {
544 Preconditions.checkNotNull(ep);
545 if (eigs == null || eigs.isEmpty()) {
548 Set<EndpointGroupId> epgs = getEpgs(ep);
549 Preconditions.checkArgument(!epgs.isEmpty());
550 for (EndpointGroupId epg : epgs) {
551 for (ExternalImplicitGroup eig : eigs) {
552 if (epg.equals(eig.getId())) {
560 private static Set<EndpointGroupId> getEpgs(EndpointFields ep) {
561 EndpointGroupId epgId = ep.getEndpointGroup();
562 List<EndpointGroupId> epgsId = ep.getEndpointGroups();
563 Set<EndpointGroupId> result = new HashSet<>();
567 if (epgsId != null) {
568 result.addAll(epgsId);
574 * Get the endpoints container from data store.
575 * Note: There are maps maintained by listener when higher performance is required.
578 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints}
580 protected Endpoints getEndpointsFromDataStore() {
582 * XXX: alagalah I wanted to avoid adding another Map. Due to not being able to
583 * get to the granularity of the L3PrefixEndpoint List within the Endpoints container
584 * in the data store, we have to pull all the Endpoints. If this causes performance issues
585 * we may have to revisit a Map in updateEndpoint but note, this Endpoint doesn't have a
587 * and hence we would have to process it outside the null location check.
589 if (dataProvider == null) {
590 LOG.error("Null DataProvider in EndpointManager getEndpointsL3Prefix");
593 ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
594 Optional<Endpoints> endpoints =
595 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointsIidWildcard(), rTx);
596 if (!endpoints.isPresent()) {
597 LOG.warn("No Endpoints present in data store.");
600 return endpoints.get();
604 * Return all L3Endpoints from data store.
607 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3}
609 protected Collection<EndpointL3> getL3Endpoints() {
610 Endpoints endpoints = getEndpointsFromDataStore();
611 if (endpoints == null || endpoints.getEndpointL3() == null) {
612 LOG.warn("No L3 Endpoints present in data store.");
615 return endpoints.getEndpointL3();
619 * Return all L3Prefix Endpoints from data store.
622 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix}
624 private Collection<EndpointL3Prefix> getEndpointsL3Prefix() {
625 Endpoints endpoints = getEndpointsFromDataStore();
626 if (endpoints == null || endpoints.getEndpointL3Prefix() == null) {
627 LOG.warn("No L3 Prefix Endpoints present in data store.");
630 return endpoints.getEndpointL3Prefix();
634 * Return all L3Prefix Endpoints which come under particular tenant
636 * @param tenantId - the
637 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId}
640 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix}
642 public Collection<EndpointL3Prefix> getEndpointsL3PrefixForTenant(final TenantId tenantId) {
643 Collection<EndpointL3Prefix> l3PrefixEndpoints = getEndpointsL3Prefix();
644 if (l3PrefixEndpoints == null) {
645 // Log message already generated in getEndpointsL3Prefix()
648 return ImmutableSet.copyOf(Collections2.filter(l3PrefixEndpoints, new Predicate<EndpointL3Prefix>() {
651 public boolean apply(EndpointL3Prefix input) {
652 return (input.getTenant().equals(tenantId));
659 * Return all L3Endpoints containing network and port address translation in augmentation
662 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3}
664 public Collection<EndpointL3> getL3EndpointsWithNat() {
665 Collection<EndpointL3> l3Endpoints = getL3Endpoints();
666 if (l3Endpoints == null) {
669 l3Endpoints = Collections2.filter(l3Endpoints, new Predicate<EndpointL3>() {
672 public boolean apply(EndpointL3 input) {
673 return !((input.getAugmentation(NatAddress.class) == null)
674 || (input.getAugmentation(NatAddress.class).getNatAddress() == null));
677 if (l3Endpoints == null) {
678 return Collections.emptySet();
680 return ImmutableSet.copyOf(l3Endpoints);
684 * Set the learning mode to the specified value
686 * @param learningMode - the learning mode to set
688 @SuppressWarnings({"UnusedParameters", "EmptyMethod"})
689 public void setLearningMode(OfOverlayConfig.LearningMode learningMode) {
694 * Get the effective list of conditions that apply to a particular endpoint.
695 * This could include additional conditions over the condition labels
696 * directly represented in the endpoint object
699 * @param endpoint - the
700 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint}
702 * @return the list of
703 * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName}
705 public List<ConditionName> getConditionsForEndpoint(Endpoint endpoint) {
706 // TODO Be alagalah From Helium: consider group conditions as well. Also
708 // endpoint updated if the endpoint group conditions change
709 if (endpoint.getCondition() != null)
710 return endpoint.getCondition();
712 return Collections.emptyList();
715 private void notifyEndpointUpdated(EpKey epKey) {
716 for (EndpointListener l : listeners) {
717 l.endpointUpdated(epKey);
721 private void notifyNodeEndpointUpdated(NodeId nodeId, EpKey epKey) {
722 for (EndpointListener l : listeners) {
723 l.nodeEndpointUpdated(nodeId, epKey);
727 private void notifyGroupEndpointUpdated(EgKey egKey, EpKey epKey) {
728 for (EndpointListener l : listeners) {
729 l.groupEndpointUpdated(egKey, epKey);
733 private boolean isValidEp(Endpoint endpoint) {
734 return (endpoint != null && endpoint.getTenant() != null
735 && (endpoint.getEndpointGroup() != null || endpoint.getEndpointGroups() != null)
736 && endpoint.getL2Context() != null && endpoint.getMacAddress() != null);
739 private boolean isValidL3Ep(EndpointL3 endpoint) {
740 return (endpoint != null && endpoint.getTenant() != null
741 && (endpoint.getEndpointGroup() != null || endpoint.getEndpointGroups() != null)
742 && endpoint.getL3Context() != null && endpoint.getIpAddress() != null);
745 private NodeId getLocation(Endpoint endpoint) {
746 if (isValidEp(endpoint)) {
747 OfOverlayContext context = endpoint.getAugmentation(OfOverlayContext.class);
749 return context.getNodeId();
754 private EpKey getEpKey(Endpoint endpoint) {
755 if (isValidEp(endpoint))
756 return new EpKey(endpoint.getL2Context(), endpoint.getMacAddress());
760 public Set<EgKey> getEgKeysForEndpoint(Endpoint ep) {
761 Set<EgKey> egKeys = new HashSet<>();
763 if (ep.getEndpointGroup() != null) {
764 egKeys.add(new EgKey(ep.getTenant(), ep.getEndpointGroup()));
766 if (ep.getEndpointGroups() != null) {
767 for (EndpointGroupId epgId : ep.getEndpointGroups()) {
768 egKeys.add(new EgKey(ep.getTenant(), epgId));
774 @SuppressWarnings("unused")
775 private Endpoint addEndpointFromL3Endpoint(EndpointL3 l3Ep, ReadWriteTransaction rwTx) {
776 // Make an indexed tenant and resolveL2BridgeDomain from L3EP containment if not L3
778 OfOverlayL3Context ofL3Ctx = l3Ep.getAugmentation(OfOverlayL3Context.class);
779 OfOverlayContext ofCtx = new OfOverlayContextBuilder(ofL3Ctx).build();
780 if (l3Ep.getNetworkContainment() instanceof L3Context) {
781 LOG.error("Cannot generate Endpoint from EndpointL3, network containment is L3Context.");
786 IndexedTenant indexedTenant;
787 Optional<Tenant> tenant =
788 readFromDs(LogicalDatastoreType.CONFIGURATION, IidFactory.tenantIid(l3Ep.getTenant()), rwTx);
789 if (tenant.isPresent()) {
790 indexedTenant = new IndexedTenant(tenant.get());
792 LOG.error("Could not find tenant {} for EndpointL3 {}", l3Ep.getTenant(), l3Ep);
796 List<L3Address> l3Address = new ArrayList<>();
797 l3Address.add(new L3AddressBuilder().setIpAddress(l3Ep.getIpAddress())
798 .setL3Context(l3Ep.getL3Context())
799 .setKey(new L3AddressKey(l3Ep.getIpAddress(), l3Ep.getL3Context()))
801 L2BridgeDomain l2Bd = indexedTenant.resolveL2BridgeDomain(l3Ep.getNetworkContainment());
802 Endpoint ep = new EndpointBuilder().setKey(new EndpointKey(l2Bd.getId(), l3Ep.getMacAddress()))
803 .setMacAddress(l3Ep.getMacAddress())
804 .setL2Context(l2Bd.getId())
805 .setEndpointGroups(l3Ep.getEndpointGroups())
806 .setTenant(l3Ep.getTenant())
807 .setL3Address(l3Address)
808 .setCondition(l3Ep.getCondition())
809 .setNetworkContainment(l3Ep.getNetworkContainment())
810 .addAugmentation(OfOverlayContext.class, ofCtx)
812 rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointIid(ep.getL2Context(), ep.getMacAddress()), ep);
816 private Set<EndpointGroupId> getEndpointGroupsFromEndpoint(Endpoint ep) {
818 return new HashSet<>();
819 Set<EndpointGroupId> epgIds = new HashSet<>();
820 if (ep.getEndpointGroups() != null) {
821 epgIds.addAll(ep.getEndpointGroups());
823 if (ep.getEndpointGroup() != null) {
824 epgIds.add(ep.getEndpointGroup());
829 protected Map<EndpointKey, EndpointL3> getL3EpWithNatByL2Key() {
830 Map<EndpointKey, EndpointL3> l3EpByL2EpKey = new HashMap<>();
832 Collection<EndpointL3> l3Eps = getL3EndpointsWithNat();
834 l3EpByL2EpKey = Collections.emptyMap();
835 return l3EpByL2EpKey;
837 for (EndpointL3 l3Ep : l3Eps) {
838 if (l3Ep.getL2Context() != null && l3Ep.getMacAddress() != null) {
839 EndpointKey epKey = new EndpointKey(l3Ep.getL2Context(), l3Ep.getMacAddress());
840 l3EpByL2EpKey.put(epKey, l3Ep);
843 if (l3EpByL2EpKey.isEmpty()) {
844 l3EpByL2EpKey = Collections.emptyMap();
846 return l3EpByL2EpKey;
849 public EgKey getEgKey(Endpoint endpoint) {
850 if (!isValidEp(endpoint))
852 return new EgKey(endpoint.getTenant(), endpoint.getEndpointGroup());