Fix EffectiveRibInWriter.writeTable()
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / EffectiveRibInWriter.java
index 95c40129dcf41dbba6c97c40e0c65db90ff9e34e..68c8c453a452042135268ea65f61a3e50c723b12 100644 (file)
@@ -353,48 +353,70 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
 
     private <R extends Route> void deleteRoutes(final InstanceIdentifier<R> routeIID,
             final R route, final WriteTransaction tx) {
-        final Optional<RouteTarget> rtMembership = RouteTargetMembeshipUtil.getRT(route);
-        if (rtMembership.isPresent()) {
-            if (PeerRole.Ebgp != this.peerImportParameters.getFromPeerRole()) {
-                this.rtCache.uncacheRoute(route);
-            }
-            this.rtMemberships.remove(rtMembership.get());
-            this.rtMembershipsUpdated = true;
-        }
+        deleteRT(route);
         tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
     }
 
-    @SuppressWarnings("unchecked")
-    private void writeTable(final WriteTransaction tx, final DataObjectModification<Tables> table) {
+    private <C extends Routes & DataObject & ChoiceIn<Tables>, S extends ChildOf<? super C>,
+            R extends Route & ChildOf<? super S> & Identifiable<I>, I extends Identifier<R>> void writeTable(
+                    final WriteTransaction tx, final DataObjectModification<Tables> table) {
+
         final Tables newTable = table.getDataAfter();
         if (newTable == null) {
+            final Tables oldTable = table.getDataBefore();
+            if (oldTable != null) {
+                final TablesKey tableKey = oldTable.key();
+                final KeyedInstanceIdentifier<Tables, TablesKey> tablePath = tablePath(tableKey);
+                LOG.trace("Delete table at {}", tablePath);
+                tx.delete(LogicalDatastoreType.OPERATIONAL, tablePath);
+
+                final RIBSupport<C, S, R, I> ribSupport = this.registry.getRIBSupport(tableKey);
+                if (ribSupport != null) {
+                    final Routes oldRoutes = oldTable.getRoutes();
+                    if (oldRoutes != null) {
+                        for (R route : ribSupport.extractAdjRibInRoutes(oldRoutes)) {
+                            deleteRT(route);
+                        }
+                    }
+                }
+            }
             return;
         }
+
         final TablesKey tableKey = newTable.key();
-        final KeyedInstanceIdentifier<Tables, TablesKey> tablePath
-                = this.effRibTables.child(Tables.class, tableKey);
+        final KeyedInstanceIdentifier<Tables, TablesKey> tablePath = tablePath(tableKey);
 
         // Create an empty table
         LOG.trace("Create Empty table at {}", tablePath);
-        if (table.getDataBefore() == null) {
-            tx.put(LogicalDatastoreType.OPERATIONAL, tablePath, new TablesBuilder()
-                    .withKey(tableKey).setAfi(tableKey.getAfi()).setSafi(tableKey.getSafi())
-                    .setAttributes(newTable.getAttributes()).build());
-        }
+        tx.put(LogicalDatastoreType.OPERATIONAL, tablePath, new TablesBuilder()
+            .withKey(tableKey).setAfi(tableKey.getAfi()).setSafi(tableKey.getSafi())
+            .setAttributes(newTable.getAttributes()).build());
 
-        final RIBSupport ribSupport = this.registry.getRIBSupport(tableKey);
-        final Routes routes = newTable.getRoutes();
-        if (ribSupport == null || routes == null) {
+        final RIBSupport<C, S, R, I> ribSupport = this.registry.getRIBSupport(tableKey);
+        if (ribSupport == null) {
+            LOG.trace("No RIB support for {}", tableKey);
             return;
         }
 
-        final DataObjectModification routesChangesContainer =
-                table.getModifiedChildContainer(ribSupport.routesCaseClass(), ribSupport.routesContainerClass());
+        writeTableRoutes(tx, tableKey, ribSupport, tablePath, newTable);
+    }
 
-        if (routesChangesContainer == null) {
-            return;
+    private <C extends Routes & DataObject & ChoiceIn<Tables>, S extends ChildOf<? super C>,
+            R extends Route & ChildOf<? super S> & Identifiable<I>, I extends Identifier<R>> void writeTableRoutes(
+                    final WriteTransaction tx, final TablesKey tableKey, final RIBSupport<C, S, R, I> ribSupport,
+                    final KeyedInstanceIdentifier<Tables, TablesKey> tablePath, final Tables newTable) {
+        final Routes routes = newTable.getRoutes();
+        if (routes != null) {
+            final Class<? extends AfiSafiType> afiSafiType = tableTypeRegistry.getAfiSafiType(ribSupport.getTablesKey())
+                    .get();
+            for (R route : ribSupport.extractAdjRibInRoutes(routes)) {
+                writeRoutes(tx, tableKey, afiSafiType, ribSupport, tablePath, route.key(), route, false);
+            }
         }
-        updateRoutes(tx, tableKey, ribSupport, tablePath, routesChangesContainer.getModifiedChildren());
+    }
+
+    private KeyedInstanceIdentifier<Tables, TablesKey> tablePath(TablesKey tableKey) {
+        return this.effRibTables.child(Tables.class, tableKey);
     }
 
     @Override
@@ -450,4 +472,15 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
     public long getTotalPrefixesInstalled() {
         return this.prefixesInstalled.values().stream().mapToLong(LongAdder::longValue).sum();
     }
+
+    private void deleteRT(final Route route) {
+        final Optional<RouteTarget> rtMembership = RouteTargetMembeshipUtil.getRT(route);
+        if (rtMembership.isPresent()) {
+            if (PeerRole.Ebgp != this.peerImportParameters.getFromPeerRole()) {
+                this.rtCache.uncacheRoute(route);
+            }
+            this.rtMemberships.remove(rtMembership.get());
+            this.rtMembershipsUpdated = true;
+        }
+    }
 }