import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepLogicalSwitchListener;
-import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepNodeListener;
+import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepPhysicalSwitchListener;
import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepRemoteMcastMacListener;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
private ElanInterfaceManager elanInterfaceManager;
private L2GatewayConnectionListener l2GwConnListener;
- private HwvtepNodeListener hwvtepNodeListener;
+ private HwvtepPhysicalSwitchListener hwvtepPhySwitchListener;
private HwvtepLocalUcastMacListener torMacsListener;
private HwvtepPhysicalLocatorListener physicalLocatorListener;
this.torMacsListener = new HwvtepLocalUcastMacListener(broker);
this.l2GwConnListener = new L2GatewayConnectionListener(broker, elanInstanceManager);
- this.hwvtepNodeListener = new HwvtepNodeListener(broker, elanInstanceManager, itmRpcService);
- this.hwvtepNodeListener.registerListener(LogicalDatastoreType.OPERATIONAL, broker);
+ this.hwvtepPhySwitchListener = new HwvtepPhysicalSwitchListener(broker, itmRpcService);
+ this.hwvtepPhySwitchListener.registerListener(LogicalDatastoreType.OPERATIONAL, broker);
physicalLocatorListener = new HwvtepPhysicalLocatorListener(broker);
try {
public void close() throws Exception {
this.torMacsListener.close();
this.l2GwConnListener.close();
- this.hwvtepNodeListener.close();
+ this.hwvtepPhySwitchListener.close();
LOG.info("ElanL2GatewayProvider Closed");
}
}
*/
package org.opendaylight.netvirt.elan.l2gw.listeners;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
+import org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
import org.opendaylight.netvirt.elan.l2gw.jobs.LogicalSwitchAddedJob;
import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
-import org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
-import org.opendaylight.genius.utils.SystemPropertyReader;
-import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
*
* @see LogicalSwitches
*/
-public class HwvtepLogicalSwitchListener
- extends AsyncDataChangeListenerBase<LogicalSwitches, HwvtepLogicalSwitchListener> {
+public class HwvtepLogicalSwitchListener extends
+ AsyncClusteredDataChangeListenerBase<LogicalSwitches, HwvtepLogicalSwitchListener> {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(HwvtepLogicalSwitchListener.class);
* (non-Javadoc)
*
* @see
- * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+ * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
* getWildCardPath()
*/
@Override
* (non-Javadoc)
*
* @see
- * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+ * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
* getDataChangeListener()
*/
@Override
- protected DataChangeListener getDataChangeListener() {
+ protected ClusteredDataChangeListener getDataChangeListener() {
return HwvtepLogicalSwitchListener.this;
}
* (non-Javadoc)
*
* @see
- * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+ * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
* getDataChangeScope()
*/
@Override
* (non-Javadoc)
*
* @see
- * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+ * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
* remove(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
* org.opendaylight.yangtools.yang.binding.DataObject)
*/
* (non-Javadoc)
*
* @see
- * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+ * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
* update(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
* org.opendaylight.yangtools.yang.binding.DataObject,
* org.opendaylight.yangtools.yang.binding.DataObject)
* (non-Javadoc)
*
* @see
- * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+ * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
* add(org.opendaylight.yangtools.yang.binding.InstanceIdentifier,
* org.opendaylight.yangtools.yang.binding.DataObject)
*/
LogicalSwitchAddedJob logicalSwitchAddedWorker = new LogicalSwitchAddedJob(
logicalSwitchName, physicalDevice, elanDevice, defaultVlanId);
- dataStoreJobCoordinator.enqueueJob(logicalSwitchAddedWorker.getJobKey(), logicalSwitchAddedWorker,
- SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
-
+ ElanClusterUtils.runOnlyInLeaderNode(logicalSwitchAddedWorker.getJobKey() ,
+ "create vlan mappings and mcast configurations",
+ logicalSwitchAddedWorker);
} catch (Exception e) {
LOG.error("Failed to handle HwVTEPLogicalSwitch - add: {}", e);
} finally {
}
}
}
-
}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.netvirt.elan.l2gw.listeners;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
-import org.opendaylight.netvirt.elan.internal.ElanInstanceManager;
-import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
-import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
-import org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase;
-import org.opendaylight.genius.mdsalutil.MDSALUtil;
-import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
-import org.opendaylight.netvirt.neutronvpn.api.l2gw.utils.L2GatewayCacheUtils;
-import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-
-public class HwvtepNodeListener
- extends AsyncClusteredDataChangeListenerBase<Node, HwvtepNodeListener> {
- private static final Logger LOG = LoggerFactory.getLogger(HwvtepNodeListener.class);
-
- private DataBroker dataBroker;
- private ItmRpcService itmRpcService;
- ElanInstanceManager elanInstanceManager;
-
- public HwvtepNodeListener(final DataBroker dataBroker, ElanInstanceManager elanInstanceManager,
- ItmRpcService itmRpcService) {
- super(Node.class, HwvtepNodeListener.class);
- this.dataBroker = dataBroker;
- this.itmRpcService = itmRpcService;
- this.elanInstanceManager = elanInstanceManager;
- }
-
- @Override
- protected InstanceIdentifier<Node> getWildCardPath() {
- return InstanceIdentifier.create(NetworkTopology.class)
- .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class);
- }
-
- @Override
- protected HwvtepNodeListener getDataChangeListener() {
- return HwvtepNodeListener.this;
- }
-
- @Override
- protected DataChangeScope getDataChangeScope() {
- return AsyncDataBroker.DataChangeScope.BASE;
- }
-
- @Override
- protected void remove(InstanceIdentifier<Node> key, Node nodeDeleted) {
- String nodeId = nodeDeleted.getNodeId().getValue();
- LOG.debug("Received Node Remove Event for {}", nodeId);
-
- PhysicalSwitchAugmentation psAugmentation = nodeDeleted.getAugmentation(PhysicalSwitchAugmentation.class);
- if (psAugmentation != null) {
- String psName = psAugmentation.getHwvtepNodeName().getValue();
- LOG.info("Physical switch {} removed from node {} event received", psName, nodeId);
-
- L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
- if (l2GwDevice != null) {
- if (!L2GatewayConnectionUtils.isGatewayAssociatedToL2Device(l2GwDevice)) {
- L2GatewayCacheUtils.removeL2DeviceFromCache(psName);
- LOG.debug("{} details removed from L2Gateway Cache", psName);
- } else {
- LOG.debug("{} details are not removed from L2Gateway Cache as it has L2Gateway refrence", psName);
- }
-
- l2GwDevice.setConnected(false);
- ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(psName);
- } else {
- LOG.error("Unable to find L2 Gateway details for {}", psName);
- }
- } else {
- LOG.trace("Received Node Remove Event for {} is not related to Physical switch; it's not processed",
- nodeId);
- }
- }
-
- @Override
- protected void update(InstanceIdentifier<Node> key, Node nodeBefore, Node nodeAfter) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Received Node Update Event: Node Before: {}, Node After: {}", nodeBefore, nodeAfter);
- }
- }
-
- @Override
- protected void add(InstanceIdentifier<Node> key, Node nodeAdded) {
- String nodeId = nodeAdded.getNodeId().getValue();
- LOG.debug("Received Node Add Event for {}", nodeId);
-
- PhysicalSwitchAugmentation psAugmentation = nodeAdded.getAugmentation(PhysicalSwitchAugmentation.class);
- if (psAugmentation != null) {
- String psName = psAugmentation.getHwvtepNodeName().getValue();
- LOG.info("Physical switch {} added to node {} event received", psName, nodeId);
-
- L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
- if (l2GwDevice == null) {
- LOG.debug("{} details are not present in L2Gateway Cache; added now!", psName);
-
- l2GwDevice = new L2GatewayDevice();
- l2GwDevice.setDeviceName(psName);
- L2GatewayCacheUtils.addL2DeviceToCache(psName, l2GwDevice);
- } else {
- LOG.debug("{} details are present in L2Gateway Cache and same reference used for updates", psName);
- }
-
- l2GwDevice.setConnected(true);
- String hwvtepNodeId = getManagedByNodeId(psAugmentation.getManagedBy());
- l2GwDevice.setHwvtepNodeId(hwvtepNodeId);
- List<TunnelIps> tunnelIps = psAugmentation.getTunnelIps();
- if (tunnelIps != null) {
- for (TunnelIps tunnelIp : tunnelIps) {
- IpAddress tunnelIpAddr = tunnelIp.getTunnelIpsKey();
- l2GwDevice.addTunnelIp(tunnelIpAddr);
- if (L2GatewayConnectionUtils.isGatewayAssociatedToL2Device(l2GwDevice)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("L2Gateway {} associated for {} physical switch; creating ITM tunnels for {}",
- l2GwDevice.getL2GatewayIds(), psName, tunnelIpAddr);
- }
-
- // It's a pre-provision scenario
- // Initiate ITM tunnel creation
- ElanL2GatewayUtils.createItmTunnels(itmRpcService, hwvtepNodeId, psName, tunnelIpAddr);
-
- // Initiate Logical switch creation for associated L2
- // Gateway Connections
- List<L2gatewayConnection> l2GwConns = getAssociatedL2GwConnections(dataBroker,
- l2GwDevice.getL2GatewayIds());
- if (l2GwConns != null) {
- LOG.debug("L2GatewayConnections associated for {} physical switch", psName);
-
- for (L2gatewayConnection l2GwConn : l2GwConns) {
- LOG.trace("L2GatewayConnection {} changes executed on physical switch {}",
- l2GwConn.getL2gatewayId(), psName);
-
- L2GatewayConnectionUtils.addL2GatewayConnection(l2GwConn, psName);
- }
- }
- //TODO handle deleted l2gw connections while the device is offline
- }
- }
- }
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("L2Gateway cache updated with below details: {}", l2GwDevice);
- }
- } else {
- LOG.trace("Received Node Add Event for {} is not related to Physical switch; it's not processed", nodeId);
- }
- }
-
- private List<L2gatewayConnection> getAssociatedL2GwConnections(DataBroker broker, List<Uuid> l2GatewayIds) {
- List<L2gatewayConnection> l2GwConnections = null;
- List<L2gatewayConnection> allL2GwConns = getAllL2gatewayConnections(broker);
- if (allL2GwConns != null) {
- l2GwConnections = new ArrayList<L2gatewayConnection>();
- for (Uuid l2GatewayId : l2GatewayIds) {
- for (L2gatewayConnection l2GwConn : allL2GwConns) {
- if (l2GwConn.getL2gatewayId().equals(l2GatewayId)) {
- l2GwConnections.add(l2GwConn);
- }
- }
- }
- }
- return l2GwConnections;
- }
-
- protected List<L2gatewayConnection> getAllL2gatewayConnections(DataBroker broker) {
- InstanceIdentifier<L2gatewayConnections> inst = InstanceIdentifier.create(Neutron.class)
- .child(L2gatewayConnections.class);
- Optional<L2gatewayConnections> l2GwConns = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
- if (l2GwConns.isPresent()) {
- return l2GwConns.get().getL2gatewayConnection();
- }
- return null;
- }
-
- private String getManagedByNodeId(HwvtepGlobalRef globalRef) {
- InstanceIdentifier<?> instId = globalRef.getValue();
- return instId.firstKeyOf(Node.class, NodeKey.class).getNodeId().getValue();
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netvirt.elan.l2gw.listeners;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
+import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
+import org.opendaylight.netvirt.elan.l2gw.utils.L2GatewayConnectionUtils;
+import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
+import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
+import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
+import org.opendaylight.netvirt.neutronvpn.api.l2gw.utils.L2GatewayCacheUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * Listener to handle physical switch updates.
+ */
+public class HwvtepPhysicalSwitchListener
+ extends AsyncDataTreeChangeListenerBase<PhysicalSwitchAugmentation, HwvtepPhysicalSwitchListener>
+ implements ClusteredDataTreeChangeListener<PhysicalSwitchAugmentation>, AutoCloseable {
+
+ /** The Constant LOG. */
+ private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchListener.class);
+
+ /** The data broker. */
+ private DataBroker dataBroker;
+
+ /** The itm rpc service. */
+ private ItmRpcService itmRpcService;
+
+ /**
+ * Instantiates a new hwvtep physical switch listener.
+ *
+ * @param dataBroker
+ * the data broker
+ * @param itmRpcService
+ * the itm rpc service
+ */
+ public HwvtepPhysicalSwitchListener(final DataBroker dataBroker, ItmRpcService itmRpcService) {
+ super(PhysicalSwitchAugmentation.class, HwvtepPhysicalSwitchListener.class);
+ this.dataBroker = dataBroker;
+ this.itmRpcService = itmRpcService;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opendaylight.vpnservice.datastoreutils.
+ * AsyncDataTreeChangeListenerBase#getWildCardPath()
+ */
+ @Override
+ protected InstanceIdentifier<PhysicalSwitchAugmentation> getWildCardPath() {
+ return InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class)
+ .augmentation(PhysicalSwitchAugmentation.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opendaylight.vpnservice.datastoreutils.
+ * AsyncDataTreeChangeListenerBase#getDataTreeChangeListener()
+ */
+ @Override
+ protected HwvtepPhysicalSwitchListener getDataTreeChangeListener() {
+ return HwvtepPhysicalSwitchListener.this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opendaylight.vpnservice.datastoreutils.
+ * AsyncDataTreeChangeListenerBase#remove(org.opendaylight.yangtools.yang.
+ * binding.InstanceIdentifier,
+ * org.opendaylight.yangtools.yang.binding.DataObject)
+ */
+ @Override
+ protected void remove(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
+ PhysicalSwitchAugmentation phySwitchDeleted) {
+ NodeId nodeId = getNodeId(identifier);
+ String psName = phySwitchDeleted.getHwvtepNodeName().getValue();
+ LOG.info("Received physical switch {} removed event for node {}", psName, nodeId.getValue());
+
+ L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
+ if (l2GwDevice != null) {
+ if (!L2GatewayConnectionUtils.isGatewayAssociatedToL2Device(l2GwDevice)) {
+ L2GatewayCacheUtils.removeL2DeviceFromCache(psName);
+ LOG.debug("{} details removed from L2Gateway Cache", psName);
+ } else {
+ LOG.debug("{} details are not removed from L2Gateway Cache as it has L2Gateway reference", psName);
+ }
+
+ l2GwDevice.setConnected(false);
+ ElanL2GwCacheUtils.removeL2GatewayDeviceFromAllElanCache(psName);
+ } else {
+ LOG.error("Unable to find L2 Gateway details for {}", psName);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opendaylight.vpnservice.datastoreutils.
+ * AsyncDataTreeChangeListenerBase#update(org.opendaylight.yangtools.yang.
+ * binding.InstanceIdentifier,
+ * org.opendaylight.yangtools.yang.binding.DataObject,
+ * org.opendaylight.yangtools.yang.binding.DataObject)
+ */
+ @Override
+ protected void update(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
+ PhysicalSwitchAugmentation phySwitchBefore, PhysicalSwitchAugmentation phySwitchAfter) {
+ NodeId nodeId = getNodeId(identifier);
+ if (LOG.isTraceEnabled()) {
+ LOG.trace(
+ "Received PhysicalSwitch Update Event for node {}: PhysicalSwitch Before: {}, PhysicalSwitch After: {}",
+ nodeId.getValue(), phySwitchBefore, phySwitchAfter);
+ }
+ String psName = phySwitchBefore.getHwvtepNodeName().getValue();
+ LOG.info("Received physical switch {} update event for node {}", psName, nodeId.getValue());
+
+ if (isTunnelIpNewlyConfigured(phySwitchBefore, phySwitchAfter)) {
+ final L2GatewayDevice l2GwDevice = updateL2GatewayCache(psName, phySwitchAfter);
+
+ ElanClusterUtils.runOnlyInLeaderNode(HwvtepSouthboundConstants.ELAN_ENTITY_NAME,
+ "handling Physical Switch add", new Callable<List<ListenableFuture<Void>>>() {
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ handleAdd(l2GwDevice);
+ return Collections.emptyList();
+ }
+ });
+ } else {
+ LOG.debug("Other updates in physical switch {} for node {}", psName, nodeId.getValue());
+ // TODO: handle tunnel ip change
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opendaylight.vpnservice.datastoreutils.
+ * AsyncDataTreeChangeListenerBase#add(org.opendaylight.yangtools.yang.
+ * binding.InstanceIdentifier,
+ * org.opendaylight.yangtools.yang.binding.DataObject)
+ */
+ @Override
+ protected void add(InstanceIdentifier<PhysicalSwitchAugmentation> identifier,
+ final PhysicalSwitchAugmentation phySwitchAdded) {
+ NodeId nodeId = getNodeId(identifier);
+ final String psName = phySwitchAdded.getHwvtepNodeName().getValue();
+ LOG.info("Received physical switch {} added event received for node {}", psName, nodeId.getValue());
+
+ final L2GatewayDevice l2GwDevice = updateL2GatewayCache(psName, phySwitchAdded);
+
+ ElanClusterUtils.runOnlyInLeaderNode(HwvtepSouthboundConstants.ELAN_ENTITY_NAME, "handling Physical Switch add",
+ new Callable<List<ListenableFuture<Void>>>() {
+ @Override
+ public List<ListenableFuture<Void>> call() throws Exception {
+ handleAdd(l2GwDevice);
+ return Collections.emptyList();
+ }
+ });
+ }
+
+ /**
+ * Handle add.
+ *
+ * @param l2GwDevice
+ * the l2 gw device
+ */
+ private void handleAdd(L2GatewayDevice l2GwDevice) {
+ String psName = l2GwDevice.getDeviceName();
+ String hwvtepNodeId = l2GwDevice.getHwvtepNodeId();
+ List<IpAddress> tunnelIps = l2GwDevice.getTunnelIps();
+ if (tunnelIps != null) {
+ for (IpAddress tunnelIpAddr : tunnelIps) {
+ if (L2GatewayConnectionUtils.isGatewayAssociatedToL2Device(l2GwDevice)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("L2Gateway {} associated for {} physical switch; creating ITM tunnels for {}",
+ l2GwDevice.getL2GatewayIds(), psName, tunnelIpAddr);
+ }
+
+ // It's a pre-provision scenario
+ // Initiate ITM tunnel creation
+ ElanL2GatewayUtils.createItmTunnels(itmRpcService, hwvtepNodeId, psName, tunnelIpAddr);
+
+ // Initiate Logical switch creation for associated L2
+ // Gateway Connections
+ List<L2gatewayConnection> l2GwConns = getAssociatedL2GwConnections(dataBroker,
+ l2GwDevice.getL2GatewayIds());
+ if (l2GwConns != null) {
+ LOG.debug("L2GatewayConnections associated for {} physical switch", psName);
+
+ for (L2gatewayConnection l2GwConn : l2GwConns) {
+ LOG.trace("L2GatewayConnection {} changes executed on physical switch {}",
+ l2GwConn.getL2gatewayId(), psName);
+
+ L2GatewayConnectionUtils.addL2GatewayConnection(l2GwConn, psName);
+ }
+ }
+ // TODO handle deleted l2gw connections while the device is
+ // offline
+ }
+ }
+ }
+ }
+
+ /**
+ * Update l2 gateway cache.
+ *
+ * @param psName
+ * the ps name
+ * @param phySwitch
+ * the phy switch
+ * @return the l2 gateway device
+ */
+ private L2GatewayDevice updateL2GatewayCache(String psName, PhysicalSwitchAugmentation phySwitch) {
+ L2GatewayDevice l2GwDevice = L2GatewayCacheUtils.getL2DeviceFromCache(psName);
+ if (l2GwDevice == null) {
+ LOG.debug("{} details are not present in L2Gateway Cache; added now!", psName);
+
+ l2GwDevice = new L2GatewayDevice();
+ l2GwDevice.setDeviceName(psName);
+ L2GatewayCacheUtils.addL2DeviceToCache(psName, l2GwDevice);
+ } else {
+ LOG.debug("{} details are present in L2Gateway Cache and same reference used for updates", psName);
+ }
+ l2GwDevice.setConnected(true);
+ String hwvtepNodeId = getManagedByNodeId(phySwitch.getManagedBy());
+ l2GwDevice.setHwvtepNodeId(hwvtepNodeId);
+
+ List<TunnelIps> tunnelIps = phySwitch.getTunnelIps();
+ if (tunnelIps != null && !tunnelIps.isEmpty()) {
+ List<IpAddress> existingTunnelIps = l2GwDevice.getTunnelIps();
+ for (TunnelIps tunnelIp : tunnelIps) {
+ IpAddress tunnelIpAddr = tunnelIp.getTunnelIpsKey();
+ if (!existingTunnelIps.contains(tunnelIpAddr)) {
+ l2GwDevice.addTunnelIp(tunnelIpAddr);
+ }
+ }
+ }
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("L2Gateway cache updated with below details: {}", l2GwDevice);
+ }
+ return l2GwDevice;
+ }
+
+ /**
+ * Gets the associated l2 gw connections.
+ *
+ * @param broker
+ * the broker
+ * @param l2GatewayIds
+ * the l2 gateway ids
+ * @return the associated l2 gw connections
+ */
+ private List<L2gatewayConnection> getAssociatedL2GwConnections(DataBroker broker, List<Uuid> l2GatewayIds) {
+ List<L2gatewayConnection> l2GwConnections = null;
+ List<L2gatewayConnection> allL2GwConns = getAllL2gatewayConnections(broker);
+ if (allL2GwConns != null) {
+ l2GwConnections = new ArrayList<L2gatewayConnection>();
+ for (Uuid l2GatewayId : l2GatewayIds) {
+ for (L2gatewayConnection l2GwConn : allL2GwConns) {
+ if (l2GwConn.getL2gatewayId().equals(l2GatewayId)) {
+ l2GwConnections.add(l2GwConn);
+ }
+ }
+ }
+ }
+ return l2GwConnections;
+ }
+
+ /**
+ * Gets the all l2gateway connections.
+ *
+ * @param broker
+ * the broker
+ * @return the all l2gateway connections
+ */
+ protected List<L2gatewayConnection> getAllL2gatewayConnections(DataBroker broker) {
+ InstanceIdentifier<L2gatewayConnections> inst = InstanceIdentifier.create(Neutron.class)
+ .child(L2gatewayConnections.class);
+ Optional<L2gatewayConnections> l2GwConns = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
+ if (l2GwConns.isPresent()) {
+ return l2GwConns.get().getL2gatewayConnection();
+ }
+ return null;
+ }
+
+ /**
+ * Gets the managed by node id.
+ *
+ * @param globalRef
+ * the global ref
+ * @return the managed by node id
+ */
+ private String getManagedByNodeId(HwvtepGlobalRef globalRef) {
+ InstanceIdentifier<?> instId = globalRef.getValue();
+ return instId.firstKeyOf(Node.class).getNodeId().getValue();
+ }
+
+ /**
+ * Gets the node id.
+ *
+ * @param identifier
+ * the identifier
+ * @return the node id
+ */
+ private NodeId getNodeId(InstanceIdentifier<PhysicalSwitchAugmentation> identifier) {
+ return identifier.firstKeyOf(Node.class).getNodeId();
+ }
+
+ /**
+ * Checks if is tunnel ip newly configured.
+ *
+ * @param phySwitchBefore
+ * the phy switch before
+ * @param phySwitchAfter
+ * the phy switch after
+ * @return true, if is tunnel ip newly configured
+ */
+ private boolean isTunnelIpNewlyConfigured(PhysicalSwitchAugmentation phySwitchBefore,
+ PhysicalSwitchAugmentation phySwitchAfter) {
+ return (phySwitchBefore.getTunnelIps() == null || phySwitchBefore.getTunnelIps().isEmpty())
+ && (phySwitchAfter.getTunnelIps() != null && !phySwitchAfter.getTunnelIps().isEmpty());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.opendaylight.vpnservice.datastoreutils.
+ * AsyncDataTreeChangeListenerBase#close()
+ */
+ @Override
+ public void close() {
+ try {
+ super.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.netvirt.elan.utils.ElanUtils;
import org.opendaylight.netvirt.elan.utils.ElanConstants;
-import org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase;
+import org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase;
import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
* @see RemoteMcastMacs
*/
public class HwvtepRemoteMcastMacListener
- extends AsyncDataChangeListenerBase<RemoteMcastMacs, HwvtepRemoteMcastMacListener> {
+ extends AsyncClusteredDataChangeListenerBase<RemoteMcastMacs, HwvtepRemoteMcastMacListener> {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(HwvtepRemoteMcastMacListener.class);
* getDataChangeListener()
*/
@Override
- protected DataChangeListener getDataChangeListener() {
+ protected ClusteredDataChangeListener getDataChangeListener() {
return HwvtepRemoteMcastMacListener.this;
}
RemoteMcastMacsKey remoteMcastMacsKey = new RemoteMcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch),
new MacAddress(ElanConstants.UNKNOWN_DMAC));
- RemoteMcastMacs remoteMcast = HwvtepUtils.getRemoteMcastMac(broker, LogicalDatastoreType.OPERATIONAL, nodeId,
- remoteMcastMacsKey);
- if (remoteMcast != null) {
- LOG.info("Deleting RemoteMcastMacs entry on node: {} for logical switch: {}", nodeId.getValue(),
- logicalSwitchName);
- return HwvtepUtils.deleteRemoteMcastMac(broker, nodeId, remoteMcastMacsKey);
- }
-
- SettableFuture<Void> future = SettableFuture.create();
- future.set(null);
- return future;
+ LOG.info("Deleting RemoteMcastMacs entry on node: {} for logical switch: {}", nodeId.getValue(),
+ logicalSwitchName);
+ return HwvtepUtils.deleteRemoteMcastMac(broker, nodeId, remoteMcastMacsKey);
}
/**
public static IpAddress getTepIpOfDesignatedSwitchForExternalTunnel(L2GatewayDevice l2GwDevice,
String elanInstanceName) {
IpAddress tepIp = null;
+ if (l2GwDevice.getTunnelIp() == null) {
+ LOG.warn("Tunnel IP not found for {}", l2GwDevice.getDeviceName());
+ return tepIp;
+ }
DesignatedSwitchForTunnel desgSwitch = getDesignatedSwitchForExternalTunnel(l2GwDevice.getTunnelIp(),
elanInstanceName);
if (desgSwitch != null) {