Support for LearntVpnVipToPort in netvirt 85/50285/1
authorKonsta Pozdeev <konsta.pozdeev@hpe.com>
Wed, 4 Jan 2017 15:41:53 +0000 (17:41 +0200)
committerDavid Goldberg <gdavid@hpe.com>
Wed, 11 Jan 2017 12:12:30 +0000 (14:12 +0200)
Change-Id: I87adb41f904edbabd7a73c8e48689e228748c7b6
Signed-off-by: Konsta Pozdeev <konsta.pozdeev@hpe.com>
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/DataWaitListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/GwMacListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtVpnUtils.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/SubnetListener.java

index ecce5e7ebdf8a011f0174458936cfa78b1b063cd..641b1502e50984e74de5b19557810c48b8b3a7ab 100644 (file)
@@ -73,6 +73,12 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
 
     @Override
     public void remove(DataTreeModification<D> removedDataObject) {
+        if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
+            Log.info("data {} deleted", removedDataObject.getRootNode().getIdentifier());
+        }
+        synchronized (lockDataAvailable) {
+            lockDataAvailable.notifyAll();
+        }
     }
 
     @Override
@@ -96,6 +102,10 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
         return waitForData(maxRetries);
     }
 
+    public boolean waitForClean() {
+        return waitForClean(maxRetries);
+    }
+
     public Object getData() {
         Optional<D> objectInstance = MdsalUtils.read(dataBroker, logicalDatastoreType, objectIdentifierId);
         if (!objectInstance.isPresent()) {
@@ -113,11 +123,28 @@ public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChange
             } else if (retry <= 0) {
                 return false;
             }
-            try {
-                lockDataAvailable.wait(waitMillisec);
-            } catch (InterruptedException e1) {
-            }
+            safeWaitLock();
         }
         return waitForData(--retry);
     }
+
+    public boolean waitForClean(int retry) {
+        synchronized (lockDataAvailable) {
+            dataAvailable = dataAvailable();
+            if (dataAvailable == false) {
+                return true;
+            } else if (retry <= 0) {
+                return false;
+            }
+            safeWaitLock();
+        }
+        return waitForClean(--retry);
+    }
+
+    private void safeWaitLock() {
+        try {
+            lockDataAvailable.wait(waitMillisec);
+        } catch (InterruptedException e1) {
+        }
+    }
 }
index a85371c8caca486cece6418bfc4f92db943bc608..f07b889b17ca71d38981378721d327a926ed1dfb 100644 (file)
@@ -8,9 +8,7 @@
 
 package org.opendaylight.unimgr.mef.netvirt;
 
-import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
@@ -24,12 +22,12 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class GwMacListener extends UnimgrDataTreeChangeListener<VpnPortipToPort> implements IGwMacListener {
+public class GwMacListener extends UnimgrDataTreeChangeListener<LearntVpnVipToPort> implements IGwMacListener {
     private static final Logger Log = LoggerFactory.getLogger(GwMacListener.class);
     private ListenerRegistration<GwMacListener> gwMacListenerRegistration;
     private final OdlArputilService arpUtilService;
@@ -49,8 +47,8 @@ public class GwMacListener extends UnimgrDataTreeChangeListener<VpnPortipToPort>
 
     public void registerListener() {
         try {
-            final DataTreeIdentifier<VpnPortipToPort> dataTreeIid = new DataTreeIdentifier<>(
-                    LogicalDatastoreType.OPERATIONAL, NetvirtVpnUtils.getVpnPortipToPortIdentifier());
+            final DataTreeIdentifier<LearntVpnVipToPort> dataTreeIid = new DataTreeIdentifier<>(
+                    LogicalDatastoreType.OPERATIONAL, NetvirtVpnUtils.getLearntVpnVipToPortIdentifier());
             gwMacListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
             startRetriesThread();
             Log.info("GwMacListener created and registered");
@@ -70,26 +68,26 @@ public class GwMacListener extends UnimgrDataTreeChangeListener<VpnPortipToPort>
     }
 
     @Override
-    public void add(DataTreeModification<VpnPortipToPort> newDataObject) {
+    public void add(DataTreeModification<LearntVpnVipToPort> newDataObject) {
         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
-            VpnPortipToPort portIpToPort = newDataObject.getRootNode().getDataAfter();
+            LearntVpnVipToPort portIpToPort = newDataObject.getRootNode().getDataAfter();
             updateMac(portIpToPort);
         }
     }
 
     @Override
-    public void remove(DataTreeModification<VpnPortipToPort> removedDataObject) {
+    public void remove(DataTreeModification<LearntVpnVipToPort> removedDataObject) {
     }
 
     @Override
-    public void update(DataTreeModification<VpnPortipToPort> modifiedDataObject) {
+    public void update(DataTreeModification<LearntVpnVipToPort> modifiedDataObject) {
         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
-            VpnPortipToPort portIpToPort = modifiedDataObject.getRootNode().getDataAfter();
+            LearntVpnVipToPort portIpToPort = modifiedDataObject.getRootNode().getDataAfter();
             updateMac(portIpToPort);
         }
     }
 
-    private synchronized void updateMac(VpnPortipToPort portIpToPort) {
+    private synchronized void updateMac(LearntVpnVipToPort portIpToPort) {
         String portName = portIpToPort.getPortName();
         String macAddress = portIpToPort.getMacAddress();
         String vpnName = portIpToPort.getVpnName();
@@ -152,7 +150,7 @@ public class GwMacListener extends UnimgrDataTreeChangeListener<VpnPortipToPort>
             gwMacResolver.get(gwMacKey).getSubnets().add(subnet);
         }
 
-        VpnPortipToPort portIpToPort = NetvirtVpnUtils.getVpnPortFixedIp(dataBroker, vpnName, dstIpAddressStr);
+        LearntVpnVipToPort portIpToPort = NetvirtVpnUtils.getLearntVpnVipToPort(dataBroker, vpnName, dstIpAddressStr);
         if (portIpToPort != null) {
             updateMac(portIpToPort);
         }
index a180cb32b3bdea172f1b43d4f0063fb148150c58..27477a08aa483504e9e85d4782cdfb8894e19ff1 100644 (file)
@@ -46,11 +46,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
@@ -204,25 +207,39 @@ public class NetvirtVpnUtils {
     }
 
     public static void removeVpnInterfaceAdjacencies(DataBroker dataBroker, String vpnName, String interfaceName) {
+
         InstanceIdentifier<VpnInterface> identifier = getVpnInterfaceInstanceIdentifier(interfaceName);
         InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
+
         Optional<Adjacencies> adjacencies = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
         List<Adjacency> adjacenciesList = adjacencies.isPresent() && adjacencies.get().getAdjacency() != null
                 ? adjacencies.get().getAdjacency() : Collections.emptyList();
         adjacenciesList.forEach(a -> {
             String ipStr = getIpAddressFromPrefix(a.getIpAddress());
-            InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, ipStr);
+            InstanceIdentifier<LearntVpnVipToPort> id = getLearntVpnVipToPortIdentifier(vpnName, ipStr);
             MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
         });
+        int waitCount = (adjacenciesList.isEmpty()) ? 2 : 2 * adjacenciesList.size();
 
         AdjacenciesBuilder builder = new AdjacenciesBuilder();
         List<Adjacency> list = new ArrayList<>();
         builder.setAdjacency(list);
         VpnInterfaceBuilder einterfaceBuilder = createVpnInterface(vpnName, interfaceName, builder.build());
+        MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier, einterfaceBuilder.build());
 
-        MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                getVpnInterfaceInstanceIdentifier(interfaceName), einterfaceBuilder.build());
+        final DataWaitGetter<Adjacencies> getData = vpnint -> {
+            if (vpnint.getAdjacency() == null)
+                return null;
+            return vpnint.getAdjacency().stream().filter(a -> !a.isPrimaryAdjacency());
+        };
 
+        @SuppressWarnings("resource") // AutoCloseable
+        DataWaitListener<Adjacencies> vpnIntWaiter = new DataWaitListener<Adjacencies>(dataBroker, path, waitCount,
+                LogicalDatastoreType.OPERATIONAL, getData);
+        if (!vpnIntWaiter.waitForClean()) {
+            logger.error("Fail to wait for VPN interface clean-up {} {}", vpnName, interfaceName);
+            return;
+        }
     }
 
     public static void removeVpnInterfaceAdjacency(DataBroker dataBroker, String interfaceName, IpPrefix ifPrefix) {
@@ -272,7 +289,7 @@ public class NetvirtVpnUtils {
             VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder()
                     .setKey(new VpnPortipToPortKey(fixedIp, vpnName)).setVpnName(vpnName).setPortFixedip(fixedIp)
                     .setPortName(portName).setMacAddress(macAddress.getValue()).setSubnetIp(true);
-            tx.put(LogicalDatastoreType.OPERATIONAL, id, builder.build());
+            tx.put(LogicalDatastoreType.CONFIGURATION, id, builder.build());
             logger.debug(
                     "Interface to fixedIp added: {}, vpn {}, interface {}, mac {} added to " + "VpnPortipToPort DS",
                     fixedIp, vpnName, portName, macAddress);
@@ -281,7 +298,13 @@ public class NetvirtVpnUtils {
 
     public static VpnPortipToPort getVpnPortFixedIp(DataBroker dataBroker, String vpnName, String fixedIp) {
         InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
-        Optional<VpnPortipToPort> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+        Optional<VpnPortipToPort> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
+        return opt != null && opt.isPresent() ? opt.get() : null;
+    }
+
+    public static LearntVpnVipToPort getLearntVpnVipToPort(DataBroker dataBroker, String vpnName, String fixedIp) {
+        InstanceIdentifier<LearntVpnVipToPort> id = getLearntVpnVipToPortIdentifier(vpnName, fixedIp);
+        Optional<LearntVpnVipToPort> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
         return opt != null && opt.isPresent() ? opt.get() : null;
     }
 
@@ -289,7 +312,7 @@ public class NetvirtVpnUtils {
         String fixedIpPrefix = ipPrefixToString(ipAddress);
         String fixedIp = getIpAddressFromPrefix(fixedIpPrefix);
         InstanceIdentifier<VpnPortipToPort> id = getVpnPortipToPortIdentifier(vpnName, fixedIp);
-        tx.delete(LogicalDatastoreType.OPERATIONAL, id);
+        tx.delete(LogicalDatastoreType.CONFIGURATION, id);
     }
 
     public static void registerDirectSubnetForVpn(DataBroker dataBroker, Uuid subnetName, IpAddress gwIpAddress) {
@@ -491,10 +514,21 @@ public class NetvirtVpnUtils {
         return id;
     }
 
+    private static InstanceIdentifier<LearntVpnVipToPort> getLearntVpnVipToPortIdentifier(String vpnName,
+            String fixedIp) {
+        InstanceIdentifier<LearntVpnVipToPort> id = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
+                .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(fixedIp, vpnName)).build();
+        return id;
+    }
+
     public static InstanceIdentifier<VpnPortipToPort> getVpnPortipToPortIdentifier() {
         return InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class).build();
     }
 
+    public static InstanceIdentifier<LearntVpnVipToPort> getLearntVpnVipToPortIdentifier() {
+        return InstanceIdentifier.builder(LearntVpnVipToPortData.class).child(LearntVpnVipToPort.class).build();
+    }
+
     private static void publishSubnetAddNotification(final NotificationPublishService notificationPublishService,
             Uuid subnetId, String subnetIp, String vpnName, Long elanTag) {
         SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
index c403a79ff8c0ad1e4fb2dda1a4e40857ec9c0350..c24de9089bf07fba1d11f66272ee4bc35269d4d4 100644 (file)
@@ -58,10 +58,10 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
             final DataTreeIdentifier<Subnet> dataTreeIid = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
                     MefInterfaceUtils.getSubnetsInstanceIdentifier());
             subnetListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
-            Log.info("IpvcDataTreeChangeListener created and registered");
+            Log.info("SubnetListener created and registered");
         } catch (final Exception e) {
-            Log.error("Ipvc DataChange listener registration failed !", e);
-            throw new IllegalStateException("Ipvc registration Listener failed.", e);
+            Log.error("SubnetListener listener registration failed !", e);
+            throw new IllegalStateException("SubnetListener registration Listener failed.", e);
         }
     }