2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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
8 package org.opendaylight.netvirt.elan.l2gw.listeners;
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.List;
13 import java.util.concurrent.Callable;
14 import java.util.concurrent.atomic.AtomicBoolean;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.hwvtep.HwvtepClusteredDataTreeChangeListener;
18 import org.opendaylight.genius.utils.SystemPropertyReader;
19 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
20 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
21 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
22 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
23 import org.opendaylight.netvirt.elan.utils.ElanConstants;
24 import org.opendaylight.netvirt.elan.utils.ElanUtils;
25 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * The listener class for listening to {@code RemoteMcastMacs}
38 * @see RemoteMcastMacs
40 public class HwvtepRemoteMcastMacListener
41 extends HwvtepClusteredDataTreeChangeListener<RemoteMcastMacs, HwvtepRemoteMcastMacListener> {
43 /** The Constant LOG. */
44 private static final Logger LOG = LoggerFactory.getLogger(HwvtepRemoteMcastMacListener.class);
47 private final NodeId nodeId;
49 private final List<IpAddress> expectedPhyLocatorIps;
51 private final ElanUtils elanUtils;
53 String logicalSwitchName;
55 AtomicBoolean executeTask = new AtomicBoolean(true);
57 Callable<List<ListenableFuture<Void>>> taskToRun;
59 private final JobCoordinator jobCoordinator;
62 * Instantiates a new remote mcast mac listener.
63 * @param broker DataBroker
64 * @param elanUtils ElanUtils
65 * @param logicalSwitchName LS name of the network
66 * @param l2GatewayDevice L2GatewayDevice
67 * @param expectedPhyLocatorIps List of IP addresses
68 * @param task List of tasks to be executed on callbacks
69 * @param jobCoordinator JobCoordinator
70 * @throws Exception throws Exception
72 public HwvtepRemoteMcastMacListener(DataBroker broker, ElanUtils elanUtils, String logicalSwitchName,
73 L2GatewayDevice l2GatewayDevice,
74 List<IpAddress> expectedPhyLocatorIps,
75 Callable<List<ListenableFuture<Void>>> task,
76 JobCoordinator jobCoordinator, HwvtepNodeHACache hwvtepNodeHACache)
78 super(RemoteMcastMacs.class, HwvtepRemoteMcastMacListener.class, hwvtepNodeHACache);
79 this.elanUtils = elanUtils;
80 this.nodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
81 this.taskToRun = task;
82 this.logicalSwitchName = logicalSwitchName;
83 this.expectedPhyLocatorIps = expectedPhyLocatorIps;
84 this.jobCoordinator = jobCoordinator;
85 LOG.info("registering the listener for mcast mac ");
86 registerListener(LogicalDatastoreType.OPERATIONAL, broker);
87 LOG.info("registered the listener for mcast mac ");
88 if (isDataPresentInOpDs(getWildCardPath())) {
89 LOG.info("mcast mac already present running the task ");
90 if (executeTask.compareAndSet(true, false)) {
96 private boolean isDataPresentInOpDs(InstanceIdentifier<RemoteMcastMacs> path) throws Exception {
97 Optional<RemoteMcastMacs> mac = elanUtils.read2(LogicalDatastoreType.OPERATIONAL, path);
98 if (!mac.isPresent()) {
101 if (this.expectedPhyLocatorIps != null && !this.expectedPhyLocatorIps.isEmpty()) {
102 RemoteMcastMacs remoteMcastMac = mac.get();
103 if (remoteMcastMac.getLocatorSet() == null || remoteMcastMac.getLocatorSet().isEmpty()) {
106 for (IpAddress ip : this.expectedPhyLocatorIps) {
107 boolean ipExists = ElanL2GatewayUtils.checkIfPhyLocatorAlreadyExistsInRemoteMcastEntry(this.nodeId,
110 LOG.trace("IP [{}] not found in RemoteMcastMacs for node [{}]", ip.stringValue(),
111 this.nodeId.getValue());
120 public InstanceIdentifier<RemoteMcastMacs> getWildCardPath() {
121 return HwvtepSouthboundUtils.createRemoteMcastMacsInstanceIdentifier(nodeId,
122 logicalSwitchName, new MacAddress(ElanConstants.UNKNOWN_DMAC));
126 protected HwvtepRemoteMcastMacListener getDataTreeChangeListener() {
131 protected void removed(InstanceIdentifier<RemoteMcastMacs> identifier, RemoteMcastMacs deleted) {
132 LOG.trace("Received Remove DataChange Notification for identifier: {}, RemoteMcastMacs: {}", identifier,
137 protected void updated(InstanceIdentifier<RemoteMcastMacs> identifier, RemoteMcastMacs old,
138 RemoteMcastMacs newdata) {
139 LOG.trace("Received Update DataChange Notification for identifier: {}, RemoteMcastMacs old: {}, new: {}."
140 + "No Action Performed.", identifier, old, newdata);
144 protected void added(InstanceIdentifier<RemoteMcastMacs> identifier, RemoteMcastMacs mcastMac) {
145 LOG.debug("Received Add DataChange Notification for identifier: {}, RemoteMcastMacs: {}", identifier, mcastMac);
146 // No isDataPresentInOpDs check is done as assuming all the expected phy
147 // locator ips will be available during add
148 if (executeTask.compareAndSet(true, false)) {
153 @SuppressWarnings("checkstyle:IllegalCatch") // TODO remove when using AutoCloseables
156 String jobKey = ElanL2GatewayUtils.getL2GatewayConnectionJobKey(nodeId.getValue());
157 jobCoordinator.enqueueJob(jobKey, taskToRun,
158 SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
160 // TODO https://git.opendaylight.org/gerrit/#/c/44145/
161 // AutoCloseables.closeAndLog(this);
164 } catch (Exception e) {
165 LOG.warn("Failed to close McastMacSwitchListener", e);