Bug 7714 - Vpn Interface not deleted from oper DS 24/51224/7
authorOlga Schukin <olga.schukin@hpe.com>
Tue, 31 Jan 2017 10:35:55 +0000 (12:35 +0200)
committerVivekanandan Narasimhan <n.vivekanandan@ericsson.com>
Mon, 6 Feb 2017 12:25:01 +0000 (12:25 +0000)
sometimes Vpn Interface not deleted from operational/l3vpn:vpn-interfaces model,
if there is more than one adjacency to this vpn interface.

Change-Id: I45e4ca20db6c5aa9f5c280fea8726a5ed8aa654b
Signed-off-by: Olga Schukin <olga.schukin@hpe.com>
vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java

index ad8f6089d46a2043c0ce0ff45de8aff4fbae09ea..8834c2473c15a9a159ed78167fbc2492fee4d9b6 100755 (executable)
@@ -116,6 +116,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroute;
+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.prefix.to._interface.vpn.ids.Prefixes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
@@ -923,7 +924,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         return null;
     }
 
-    private boolean deleteLabelRouteInfo(LabelRouteInfo lri, String vpnInstanceName) {
+    private boolean deleteLabelRouteInfo(LabelRouteInfo lri, String vpnInstanceName, WriteTransaction tx) {
         LOG.debug("deleting LRI : for label {} vpninstancename {}", lri.getLabel(), vpnInstanceName);
         InstanceIdentifier<LabelRouteInfo> lriId = InstanceIdentifier.builder(LabelRouteMap.class)
             .child(LabelRouteInfo.class, new LabelRouteInfoKey(lri.getLabel())).build();
@@ -938,7 +939,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         }
         if (vpnInstancesList.size() == 0) {
             LOG.debug("deleting LRI instance object for label {}", lri.getLabel());
-            FibUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, lriId);
+            if (tx != null) {
+                tx.delete(LogicalDatastoreType.OPERATIONAL, lriId);
+            } else {
+                FibUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL, lriId);
+            }
             return true;
         } else {
             LOG.debug("updating LRI instance object for label {}", lri.getLabel());
@@ -1314,6 +1319,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         public List<ListenableFuture<Void>> call() throws Exception {
             // If another renderer(for eg : CSS) needs to be supported, check can be performed here
             // to call the respective helpers.
+            WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
 
             //First Cleanup LabelRouteInfo
             synchronized (vrfEntry.getLabel().toString().intern()) {
@@ -1326,7 +1332,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                     if (vpnInstanceOpDataEntryOptional.isPresent()) {
                         vpnInstanceName = vpnInstanceOpDataEntryOptional.get().getVpnInstanceName();
                     }
-                    boolean lriRemoved = deleteLabelRouteInfo(lri, vpnInstanceName);
+                    boolean lriRemoved = deleteLabelRouteInfo(lri, vpnInstanceName, writeOperTxn);
                     if (lriRemoved) {
                         String parentRd = lri.getParentVpnRd();
                         FibUtil.releaseId(idManager, FibConstants.VPN_IDPOOL_NAME,
@@ -1353,7 +1359,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                 }
             }
             if (extraRoute != null) {
-                FibUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
                     FibUtil.getVpnToExtrarouteIdentifier(rd, vrfEntry.getDestPrefix()));
             }
             Optional<Adjacencies> optAdjacencies = FibUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
@@ -1364,17 +1370,31 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
             }
             //remove adjacency corr to prefix
             if (numAdj > 1) {
-                LOG.info("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId, vrfEntry.getDestPrefix());
-                FibUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                    FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
+                boolean isPrimaryAdj = false;
+                List<Adjacency> adjacencyList = optAdjacencies.get().getAdjacency();
+                for (Adjacency adj : adjacencyList) {
+                    if (adj.getIpAddress().equals(vrfEntry.getDestPrefix())) {
+                        isPrimaryAdj = adj.isPrimaryAdjacency();
+                        break;
+                    }
+                }
+                //We should only delete secondary adjacencies, as primary adjacency is used to
+                //cleanup prefix-to-interface in the subscriber vpnInterfaceOpListener
+                if (!isPrimaryAdj) {
+                    LOG.info("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId,
+                            vrfEntry.getDestPrefix());
+                    writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
+                            FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
+                }
             }
             if ((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up
                 //clean up the vpn interface from DpnToVpn list
                 LOG.trace("Clean up vpn interface {} from dpn {} to vpn {} list.", ifName, prefixInfo.getDpnId(), rd);
-                FibUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
-                    FibUtil.getVpnInterfaceIdentifier(ifName));
+                writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, FibUtil.getVpnInterfaceIdentifier(ifName));
             }
-            return null;
+            List<ListenableFuture<Void>> futures = new ArrayList<>();
+            futures.add(writeOperTxn.submit());
+            return futures;
         }
     }
 
@@ -1423,7 +1443,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                     if (vpnInstanceOpDataEntryOptional.isPresent()) {
                         vpnInstanceName = vpnInstanceOpDataEntryOptional.get().getVpnInstanceName();
                     }
-                    boolean lriRemoved = this.deleteLabelRouteInfo(lri, vpnInstanceName);
+                    boolean lriRemoved = this.deleteLabelRouteInfo(lri, vpnInstanceName, null);
                     if (lriRemoved) {
                         String parentRd = lri.getParentVpnRd();
                         FibUtil.releaseId(idManager, FibConstants.VPN_IDPOOL_NAME,