Merge "Enable NetVirt Maven site"
authorSam Hague <shague@redhat.com>
Sun, 29 May 2016 17:01:28 +0000 (17:01 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 29 May 2016 17:01:28 +0000 (17:01 +0000)
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/internal/ElanL2GatewayProvider.java
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepLogicalSwitchListener.java
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepNodeListener.java [deleted file]
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepPhysicalSwitchListener.java [new file with mode: 0644]
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepRemoteMcastMacListener.java
vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/utils/ElanL2GatewayMulticastUtils.java

index 529d6e2fbbb8649782e53e5fcb6065c4c65c2558..c3c78cd44303b9997fb8276fa094814538ea6180 100644 (file)
@@ -13,7 +13,7 @@ import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlready
 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;
@@ -46,7 +46,7 @@ public class ElanL2GatewayProvider implements AutoCloseable {
     private ElanInterfaceManager elanInterfaceManager;
 
     private L2GatewayConnectionListener l2GwConnListener;
-    private HwvtepNodeListener hwvtepNodeListener;
+    private HwvtepPhysicalSwitchListener hwvtepPhySwitchListener;
     private HwvtepLocalUcastMacListener torMacsListener;
     private HwvtepPhysicalLocatorListener physicalLocatorListener;
 
@@ -93,8 +93,8 @@ public class ElanL2GatewayProvider implements AutoCloseable {
 
         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 {
@@ -115,7 +115,7 @@ public class ElanL2GatewayProvider implements AutoCloseable {
     public void close() throws Exception {
         this.torMacsListener.close();
         this.l2GwConnListener.close();
-        this.hwvtepNodeListener.close();
+        this.hwvtepPhySwitchListener.close();
         LOG.info("ElanL2GatewayProvider Closed");
     }
 }
index 6de0d0479f8cb9261c32ed99403ceff9ef0b2310..855ea8e1a9aba4cc9b4e937f73df33cb7997412f 100644 (file)
@@ -7,15 +7,15 @@
  */
 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;
@@ -31,8 +31,8 @@ import org.slf4j.LoggerFactory;
  *
  * @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);
@@ -90,7 +90,7 @@ public class HwvtepLogicalSwitchListener
      * (non-Javadoc)
      *
      * @see
-     * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+     * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
      * getWildCardPath()
      */
     @Override
@@ -103,11 +103,11 @@ public class HwvtepLogicalSwitchListener
      * (non-Javadoc)
      *
      * @see
-     * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+     * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
      * getDataChangeListener()
      */
     @Override
-    protected DataChangeListener getDataChangeListener() {
+    protected ClusteredDataChangeListener getDataChangeListener() {
         return HwvtepLogicalSwitchListener.this;
     }
 
@@ -115,7 +115,7 @@ public class HwvtepLogicalSwitchListener
      * (non-Javadoc)
      *
      * @see
-     * org.opendaylight.genius.datastoreutils.AsyncDataChangeListenerBase#
+     * org.opendaylight.genius.datastoreutils.AsyncClusteredDataChangeListenerBase#
      * getDataChangeScope()
      */
     @Override
@@ -127,7 +127,7 @@ public class HwvtepLogicalSwitchListener
      * (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)
      */
@@ -141,7 +141,7 @@ public class HwvtepLogicalSwitchListener
      * (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)
@@ -157,7 +157,7 @@ public class HwvtepLogicalSwitchListener
      * (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)
      */
@@ -171,9 +171,9 @@ public class HwvtepLogicalSwitchListener
 
             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 {
@@ -188,5 +188,4 @@ public class HwvtepLogicalSwitchListener
             }
         }
     }
-
 }
\ No newline at end of file
diff --git a/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepNodeListener.java b/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepNodeListener.java
deleted file mode 100644 (file)
index 23fa1cf..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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();
-    }
-}
diff --git a/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepPhysicalSwitchListener.java b/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/listeners/HwvtepPhysicalSwitchListener.java
new file mode 100644 (file)
index 0000000..ad89bf4
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * 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();
+        }
+    }
+}
index 377092cff2c3e6dade8fd297c7e6a64d1eb4a5b0..74ee0b191975d0ba6230e5b4b9479fb706669290 100644 (file)
@@ -11,13 +11,13 @@ import java.util.List;
 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;
@@ -41,7 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture;
  * @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);
@@ -148,7 +148,7 @@ public class HwvtepRemoteMcastMacListener
      * getDataChangeListener()
      */
     @Override
-    protected DataChangeListener getDataChangeListener() {
+    protected ClusteredDataChangeListener getDataChangeListener() {
         return HwvtepRemoteMcastMacListener.this;
     }
 
index 965439ff5650cd40f37f831f46037e14058e4550..e8fa9f4f5b025131204efdab20174d55335880c0 100644 (file)
@@ -372,17 +372,9 @@ public class ElanL2GatewayMulticastUtils {
         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);
     }
 
     /**
@@ -397,6 +389,10 @@ public class ElanL2GatewayMulticastUtils {
     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) {