+ // Performs house-keeping when the contents of a table is deleted
+ private void onDeleteTable(final RIBSupport<?, ?, ?, ?> ribSupport, final YangInstanceIdentifier effectiveTablePath,
+ final Optional<NormalizedNode<?, ?>> tableBefore) {
+ // Routes are special in that we need to process the to keep our counters accurate
+ final Optional<NormalizedNode<?, ?>> maybeRoutesBefore = findRoutesMap(ribSupport,
+ NormalizedNodes.findNode(tableBefore, ROUTES_NID));
+ if (maybeRoutesBefore.isPresent()) {
+ onRoutesDeleted(ribSupport, effectiveTablePath, extractMap(maybeRoutesBefore).getValue());
+ }
+ }
+
+ private void deleteRoutesBefore(final DOMDataTreeWriteTransaction tx, final RIBSupport<?, ?, ?, ?> ribSupport,
+ final YangInstanceIdentifier effectiveTablePath, final DataTreeCandidateNode modifiedRoutes) {
+ final Optional<NormalizedNode<?, ?>> maybeRoutesBefore = NormalizedNodes.findNode(
+ modifiedRoutes.getDataBefore(), ribSupport.relativeRoutesPath());
+ if (maybeRoutesBefore.isPresent()) {
+ onRoutesDeleted(ribSupport, effectiveTablePath, extractMap(maybeRoutesBefore).getValue());
+ }
+ }
+
+ private void writeRoutesAfter(final DOMDataTreeWriteTransaction tx, final RIBSupport<?, ?, ?, ?> ribSupport,
+ final YangInstanceIdentifier effectiveTablePath, final Optional<NormalizedNode<?, ?>> routesAfter,
+ final boolean longLivedStale) {
+ final Optional<NormalizedNode<?, ?>> maybeRoutesAfter = NormalizedNodes.findNode(routesAfter,
+ ribSupport.relativeRoutesPath());
+ if (maybeRoutesAfter.isPresent()) {
+ final YangInstanceIdentifier routesPath = routeMapPath(ribSupport, effectiveTablePath);
+ for (MapEntryNode routeAfter : extractMap(maybeRoutesAfter).getValue()) {
+ writeRoute(tx, ribSupport, routesPath.node(routeAfter.getIdentifier()), Optional.empty(), routeAfter,
+ longLivedStale);
+ }
+ }
+ }
+
+ private void onRoutesDeleted(final RIBSupport<?, ?, ?, ?> ribSupport,
+ final YangInstanceIdentifier effectiveTablePath, final Collection<MapEntryNode> deletedRoutes) {
+ if (ribSupport.getSafi() == RouteTargetConstrainSubsequentAddressFamily.class) {
+ final YangInstanceIdentifier routesPath = routeMapPath(ribSupport, effectiveTablePath);
+ for (final MapEntryNode routeBefore : deletedRoutes) {
+ deleteRouteTarget(ribSupport, routesPath.node(routeBefore.getIdentifier()), routeBefore);
+ }
+ this.rtMembershipsUpdated = true;
+ }
+
+ final TablesKey tablesKey = ribSupport.getTablesKey();
+ CountersUtil.add(prefixesInstalled.get(tablesKey), tablesKey, -deletedRoutes.size());
+ }
+
+ private void processRoute(final DOMDataTreeWriteTransaction tx, final RIBSupport<?, ?, ?, ?> ribSupport,
+ final YangInstanceIdentifier routesPath, final DataTreeCandidateNode route, final boolean longLivedStale) {
+ LOG.debug("Process route {}", route.getIdentifier());
+ final YangInstanceIdentifier routePath = ribSupport.routePath(routesPath, route.getIdentifier());
+ switch (route.getModificationType()) {
+ case DELETE:
+ case DISAPPEARED:
+ deleteRoute(tx, ribSupport, routePath, route.getDataBefore().orElse(null));
+ break;
+ case UNMODIFIED:
+ // No-op
+ break;
+ case APPEARED:
+ case SUBTREE_MODIFIED:
+ case WRITE:
+ writeRoute(tx, ribSupport, routePath, route.getDataBefore(), route.getDataAfter().get(),
+ longLivedStale);
+ break;
+ default:
+ LOG.warn("Ignoring unhandled route {}", route);
+ break;