Service ( IPVC ) deletion 20/52820/1
authorKonsta Pozdeev <konsta.pozdeev@hpe.com>
Mon, 30 Jan 2017 15:05:42 +0000 (17:05 +0200)
committerKonsta Pozdeev <konsta.pozdeev@hpe.com>
Sun, 5 Mar 2017 09:39:30 +0000 (11:39 +0200)
Change-Id: I4977f8b915b1c502044a2d286d6cd5a43cc4f301
Signed-off-by: Konsta Pozdeev <konsta.pozdeev@hpe.com>
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/IpvcListener.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/NetvirtVpnUtils.java
netvirt/src/main/java/org/opendaylight/unimgr/mef/netvirt/SubnetListener.java

index d4e6cfcac1ea3e1e35717d1e034317bc97ae8cc8..471021ebb3b68f050ba92ae9590704a5fd4876cb 100644 (file)
@@ -43,6 +43,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+
 public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements IUniAwareService {
     private static final Logger Log = LoggerFactory.getLogger(IpvcListener.class);
     private final IUniPortManager uniPortManager;
@@ -174,14 +176,10 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
                 Log.error("Ipvc {} hasn't been created as required, Nothing to disconnect", ipvcSerId);
                 return;
             }
-            String vpnName = operIpvcVpn.getVpnId();
 
-            synchronized (vpnName.intern()) {
-                WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
-                removeUnis(ipvcId, operIpvcVpn, toRemove, tx);
-                MdsalUtils.commitTransaction(tx);
-            }
+            removeUnis(ipvcId, operIpvcVpn, toRemove);
         }
+
     }
 
     private void addIpvc(DataTreeModification<Ipvc> newDataObject) {
@@ -246,18 +244,11 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
                 Log.error("Ipvc {} hasn't been created as required", ipvc.getIpvcId());
                 return;
             }
-            String vpnName = operIpvcVpn.getVpnId();
-
-            synchronized (vpnName.intern()) {
-                // remove elan/vpn interfaces
-                // must be in different transactios
-                WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
-                removeUnis(ipvcId, operIpvcVpn, ipvc.getUnis().getUni(), tx);
-                MdsalUtils.commitTransaction(tx);
-                // Let to work for listeners
-                // TODO : change to listener
-                NetvirtUtils.safeSleep();
+            removeUnis(ipvcId, operIpvcVpn, ipvc.getUnis().getUni());
+            NetvirtUtils.safeSleep();
 
+            String vpnId = operIpvcVpn.getVpnId();
+            synchronized (vpnId.intern()) {
                 WriteTransaction txvpn = MdsalUtils.createTransaction(dataBroker);
                 NetvirtVpnUtils.removeVpnInstance(operIpvcVpn.getVpnId(), txvpn);
                 MefServicesUtils.removeOperIpvcVpn(ipvcId, txvpn);
@@ -268,8 +259,7 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
         }
     }
 
-    private void removeUnis(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn operIpvcVpn, List<Uni> uniToRemove,
-            WriteTransaction tx) {
+    private void removeUnis(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn operIpvcVpn, List<Uni> uniToRemove) {
         if (uniToRemove == null) {
             Log.trace("No UNI's to remove");
         }
@@ -285,7 +275,7 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
 
             removeDirectSubnet(uni, ipUni);
             subnetManager.unAssignIpUniNetworks(uni.getUniId(), ipUni.getIpUniId(), ipvcId);
-            removeInterfaces(ipvcId, operIpvcVpn, uni, ipUni, tx);
+            removeInterfaces(ipvcId, operIpvcVpn, uni, ipUni);
         }
         updateQos(uniToRemove);
     }
@@ -329,9 +319,10 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
                 WriteTransaction txRemove = MdsalUtils.createTransaction(dataBroker);
                 List<Uni> uniToRemove = new ArrayList<>(originalUni);
                 uniToRemove.removeIf(u -> updateUniIds.contains(u.getKey()));
-                removeUnis(ipvcId, operIpvcVpn, uniToRemove, txRemove);
+                removeUnis(ipvcId, operIpvcVpn, uniToRemove);
                 MdsalUtils.commitTransaction(txRemove);
             }
+
             List<Uni> uniToCreate = new ArrayList<>(updateUni);
             uniToCreate.removeIf(u -> originalUniIds.contains(u.getKey()));
             createUnis(vpnName, ipvcId, uniToCreate, rd);
@@ -387,7 +378,6 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
         }
     }
 
-
     private String createElanInterface(String vpnName, InstanceIdentifier<Ipvc> ipvcId, String uniId, String elanName,
             Long vlan, IpAddress ipAddress, WriteTransaction tx, Long segmentationId) {
         Log.info("Adding elan instance: " + elanName);
@@ -415,10 +405,8 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
             IpUni ipUni, String interfaceName, String elanName, WriteTransaction tx) {
 
         Log.info("Adding vpn interface: " + interfaceName);
-
         NetvirtVpnUtils.createUpdateVpnInterface(vpnName, interfaceName, ipUni.getIpAddress(),
                 uni.getMacAddress().getValue(), true, null, elanName, tx);
-
         Log.info("Finished working on vpn instance {} interface () ", vpnName, interfaceName);
     }
 
@@ -435,8 +423,7 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
         MdsalUtils.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, subnet.build());
     }
 
-    private void removeInterfaces(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn ipvcVpn, Uni uniInService, IpUni ipUni,
-            WriteTransaction tx) {
+    private void removeInterfaces(InstanceIdentifier<Ipvc> ipvcId, IpvcVpn ipvcVpn, Uni uniInService, IpUni ipUni) {
         String uniId = uniInService.getUniId().getValue();
         String vpnName = ipvcVpn.getVpnId();
         VpnElans vpnElans = MefServicesUtils.findVpnElanForNetwork(new Identifier45(uniId), ipUni.getIpUniId(),
@@ -446,18 +433,59 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
             return;
         }
 
-        NetvirtVpnUtils.removeVpnInterfaceAdjacencies(dataBroker, vpnName, vpnElans.getElanPort());
-        // TODO : change to listener
-        NetvirtUtils.safeSleep();
-        uniQosManager.unMapUniPortBandwidthLimits(uniId, vpnElans.getElanPort());
-        removeElan(vpnElans, uniId, ipUni, tx);
-        // record Uni bw limits
-        removeVpnInterface(vpnName, vpnElans, uniId, ipUni, tx);
-        MefServicesUtils.removeOperIpvcElan(dataBroker, ipvcId, ipvcVpn.getVpnId(), uniInService.getUniId(),
-                uniInService.getIpUniId(), vpnElans.getElanId(), vpnElans.getElanPort());
+        synchronized (vpnName.intern()) {
+            uniQosManager.unMapUniPortBandwidthLimits(uniId, vpnElans.getElanPort());
+            NetvirtVpnUtils.removeLearnedVpnVipToPort(dataBroker, vpnName, vpnElans.getElanPort());
+            removeVpnInterface(vpnName, vpnElans, uniId, ipUni);
+        }
+        waitForInterfaceDpnClean(vpnName, ipvcVpn.getVrfId(), vpnElans.getElanPort());
+
+        synchronized (vpnName.intern()) {
+            removeElan(vpnElans, uniId, ipUni);
+            MefServicesUtils.removeOperIpvcElan(dataBroker, ipvcId, ipvcVpn.getVpnId(), uniInService.getUniId(),
+                    uniInService.getIpUniId(), vpnElans.getElanId(), vpnElans.getElanPort());
+        }
+    }
+
+    private void waitForInterfaceDpnClean(String vpnName, String rd, String interfaceName) {
+        InstanceIdentifier<VpnInstanceOpDataEntry> vpnId = NetvirtVpnUtils.getVpnInstanceOpDataIdentifier(rd);
+        DataWaitGetter<VpnInstanceOpDataEntry> getInterfByName = (vpn) -> {
+            if (vpn.getVpnToDpnList() == null)
+                return null;
+            for (VpnToDpnList is : vpn.getVpnToDpnList()) {
+                if (is.getVpnInterfaces() == null)
+                    continue;
+                for (VpnInterfaces i : is.getVpnInterfaces()) {
+                    if (i.getInterfaceName().equals(interfaceName))
+                        return interfaceName;
+                }
+            }
+            return null;
+        };
+
+        int retryCount = 2;
+        Optional<VpnInstanceOpDataEntry> vpnOper = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, vpnId);
+        if (vpnOper.isPresent() && vpnOper.get().getVpnToDpnList() != null) {
+            for (VpnToDpnList vpnList : vpnOper.get().getVpnToDpnList()) {
+                if (vpnList.getVpnInterfaces() != null) {
+                    retryCount = retryCount + 2 * vpnList.getVpnInterfaces().size();
+                }
+            }
+        }
+
+        @SuppressWarnings("resource")
+        DataWaitListener<VpnInstanceOpDataEntry> vpnInstanceWaiter = new DataWaitListener<>(dataBroker, vpnId,
+                retryCount, LogicalDatastoreType.OPERATIONAL, getInterfByName);
+        if (!vpnInstanceWaiter.waitForClean()) {
+            String errorMessage = String.format("Fail to wait for vpn to dpn list clean-up %s", vpnName);
+            Log.error(errorMessage);
+            throw new UnsupportedOperationException(errorMessage);
+        }
     }
 
-    private void removeElan(VpnElans vpnElans, String uniId, IpUni ipUni, WriteTransaction tx) {
+    private void removeElan(VpnElans vpnElans, String uniId, IpUni ipUni) {
+        WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+
         Long vlan = ipUni.getVlan() != null ? Long.valueOf(ipUni.getVlan().getValue()) : 0;
         Log.info("Removing trunk interface for uni {} vlan: {}", uniId, vlan);
         uniPortManager.removeCeVlan(uniId, vlan);
@@ -469,14 +497,21 @@ public class IpvcListener extends UnimgrDataTreeChangeListener<Ipvc> implements
         NetvirtVpnUtils.unregisterDirectSubnetForVpn(dataBroker, new Uuid(elanName));
         NetvirtUtils.deleteElanInterface(interfaceName, tx);
         NetvirtUtils.deleteElanInstance(elanName, tx);
+        MdsalUtils.commitTransaction(tx);
     }
 
     private void removeVpnInterface(String vpnName, VpnElans vpnElans, String uniId, IpUni ipUni, WriteTransaction tx) {
         String interfaceName = vpnElans.getElanPort();
-        Log.info("Removing vpn interface: " + interfaceName);
         NetvirtVpnUtils.removeVpnInterface(interfaceName, tx);
         NetvirtVpnUtils.removeVpnPortFixedIp(vpnName, ipUni.getIpAddress(), tx);
-        Log.info("Finished working on vpn instance: " + vpnName);
+    }
+
+    private void removeVpnInterface(String vpnName, VpnElans vpnElans, String uniId, IpUni ipUni) {
+        Log.info("Removing vpn interface: " + vpnElans.getElanPort());
+        WriteTransaction tx = MdsalUtils.createTransaction(dataBroker);
+        removeVpnInterface(vpnName, vpnElans, uniId, ipUni, tx);
+        MdsalUtils.commitTransaction(tx);
+        Log.info("Finished working on vpn interface: " + vpnElans.getElanPort());
     }
 
     private void removeDirectSubnet(Uni uni, IpUni ipUni) {
index 7fe1dd1c69292b5393fed592d4a952232c7dae86..dcfaa7ec13a50331881640c70721d61fccd2c2ca 100644 (file)
@@ -206,7 +206,7 @@ public class NetvirtVpnUtils {
         }
     }
 
-    public static void removeVpnInterfaceAdjacencies(DataBroker dataBroker, String vpnName, String interfaceName) {
+    public static void removeLearnedVpnVipToPort(DataBroker dataBroker, String vpnName, String interfaceName) {
 
         InstanceIdentifier<VpnInterface> identifier = getVpnInterfaceInstanceIdentifier(interfaceName);
         InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
@@ -217,7 +217,9 @@ public class NetvirtVpnUtils {
         adjacenciesList.forEach(a -> {
             String ipStr = getIpAddressFromPrefix(a.getIpAddress());
             InstanceIdentifier<LearntVpnVipToPort> id = getLearntVpnVipToPortIdentifier(vpnName, ipStr);
-            MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+            if (MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).isPresent()) {
+                MdsalUtils.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+            }
         });
         int waitCount = adjacenciesList.isEmpty() ? 2 : 2 * adjacenciesList.size();
 
@@ -273,6 +275,23 @@ public class NetvirtVpnUtils {
                 .child(VpnInterface.class, new VpnInterfaceKey(interfaceName)).build();
     }
 
+    public static void cleanVpnInterfaceInstanceOpt(DataBroker dataBroker, String vpnName) {
+        InstanceIdentifier<VpnInterfaces> path = InstanceIdentifier.builder(VpnInterfaces.class).build();
+
+        Optional<VpnInterfaces> opt = MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
+        if (!opt.isPresent() || opt.get().getVpnInterface() == null) {
+            return;
+        }
+
+        for (VpnInterface interf : opt.get().getVpnInterface()) {
+            if (interf.getVpnInstanceName().equals(vpnName) && interf.isScheduledForRemove()) {
+                InstanceIdentifier<VpnInterface> interfId = path.child(VpnInterface.class,
+                        new VpnInterfaceKey(interf.getKey()));
+                MdsalUtils.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, interfId);
+            }
+        }
+    }
+
     public static void createVpnPortFixedIp(DataBroker dataBroker, String vpnName, String portName, IpPrefix ipAddress,
             MacAddress macAddress) {
         String fixedIpPrefix = ipPrefixToString(ipAddress);
@@ -351,8 +370,8 @@ public class NetvirtVpnUtils {
         InstanceIdentifier<ElanInstance> elanIdentifierId = NetvirtUtils.getElanInstanceInstanceIdentifier(subnetName);
 
         @SuppressWarnings("resource") // AutoCloseable
-        DataWaitListener<ElanInstance> elanTagWaiter = new DataWaitListener<>(dataBroker, elanIdentifierId,
-                10, LogicalDatastoreType.CONFIGURATION, el -> el.getElanTag());
+        DataWaitListener<ElanInstance> elanTagWaiter = new DataWaitListener<>(dataBroker, elanIdentifierId, 10,
+                LogicalDatastoreType.CONFIGURATION, el -> el.getElanTag());
         if (!elanTagWaiter.waitForData()) {
             logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
             return;
@@ -386,7 +405,7 @@ public class NetvirtVpnUtils {
         Optional<ElanInstance> elanInstance = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
                 elanIdentifierId);
         if (!elanInstance.isPresent()) {
-            logger.error("Trying to add invalid elan {} to vpn {}", subnetName, vpnName);
+            logger.error("Trying to remove invalid elan {} to vpn {}", subnetName, vpnName);
             return;
         }
         Long elanTag = elanInstance.get().getElanTag() != null ? elanInstance.get().getElanTag()
index c24de9089bf07fba1d11f66272ee4bc35269d4d4..1cd26f68861731f4f1c4617109f3c553d210e251 100644 (file)
@@ -134,7 +134,7 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
     private void createNetwork(Subnet newSubnet, Identifier45 nwUniId, Identifier45 nwIpUniId) {
         String subnetStr = NetvirtVpnUtils.ipPrefixToString(newSubnet.getSubnet());
 
-        InstanceIdentifier<Ipvc> ipvcId = findService(nwUniId, nwIpUniId);
+        InstanceIdentifier<Ipvc> ipvcId = findService(nwUniId, nwIpUniId, getMefServices());
         if (ipvcId == null) {
             Log.info("Subnet Uni {} IpUNI {} is not assosiated to service", nwUniId, nwIpUniId);
             return;
@@ -214,7 +214,7 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
         Subnet deletedSubnet = deletedDataObject.getRootNode().getDataBefore();
         Identifier45 dlUniId = deletedSubnet.getUniId();
         Identifier45 dlIpUniId = deletedSubnet.getIpUniId();
-        InstanceIdentifier<Ipvc> ipvcId = findService(dlUniId, dlIpUniId);
+        InstanceIdentifier<Ipvc> ipvcId = findService(dlUniId, dlIpUniId, getMefServicesOper());
         if (ipvcId == null) {
             Log.info("Subnet Uni {} IpUNI {} for deleted network is not assosiated to service", dlUniId, dlIpUniId);
             return;
@@ -300,9 +300,18 @@ public class SubnetListener extends UnimgrDataTreeChangeListener<Subnet> impleme
         NetvirtVpnUtils.removeVpnInterfaceAdjacency(dataBroker, vpnElan.getElanPort(), deletedSubnet.getGateway());
     }
 
-    private InstanceIdentifier<Ipvc> findService(Identifier45 uniId, Identifier45 ipUniId) {
+    Optional<MefServices> getMefServices() {
         InstanceIdentifier<MefServices> path = MefServicesUtils.getMefServicesInstanceIdentifier();
-        Optional<MefServices> mefServices = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
+        return MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, path);
+    }
+
+    Optional<MefServices> getMefServicesOper() {
+        InstanceIdentifier<MefServices> path = MefServicesUtils.getMefServicesInstanceIdentifier();
+        return MdsalUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, path);
+    }
+
+    private InstanceIdentifier<Ipvc> findService(Identifier45 uniId, Identifier45 ipUniId,
+            Optional<MefServices> mefServices) {
         if (!mefServices.isPresent() || mefServices.get() == null) {
             Log.info("Uni {} IpUni {} is not assosiated with service", uniId, ipUniId);
             return null;