+ table.getModifiedChild(ATTRIBUTES_NID).ifPresent(modifiedAttrs -> {
+ final YangInstanceIdentifier effAttrsPath = effectiveTablePath.node(ATTRIBUTES_NID);
+ final Optional<NormalizedNode<?, ?>> optAttrsAfter = modifiedAttrs.getDataAfter();
+ if (optAttrsAfter.isPresent()) {
+ tx.put(LogicalDatastoreType.OPERATIONAL, effAttrsPath, effectiveAttributes(
+ NormalizedNodes.findNode(optAttrsAfter.get(), UPTODATE_NID)));
+ } else {
+ tx.delete(LogicalDatastoreType.OPERATIONAL, effAttrsPath);
+ }
+ });
+
+ table.getModifiedChild(ROUTES_NID).ifPresent(modifiedRoutes -> {
+ final RIBSupport<?, ?, ?, ?> ribSupport = ribContext.getRibSupport();
+ switch (modifiedRoutes.getModificationType()) {
+ case APPEARED:
+ case WRITE:
+ deleteRoutesBefore(tx, ribSupport, effectiveTablePath, modifiedRoutes);
+ // XXX: YANG Tools seems to have an issue stacking DELETE with child WRITE
+ tx.put(LogicalDatastoreType.OPERATIONAL, effectiveTablePath.node(ROUTES_NID), EMPTY_ROUTES);
+ writeRoutesAfter(tx, ribSupport, effectiveTablePath, modifiedRoutes.getDataAfter(), longLivedStale);
+ break;
+ case DELETE:
+ case DISAPPEARED:
+ deleteRoutesBefore(tx, ribSupport, effectiveTablePath, modifiedRoutes);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, effectiveTablePath.node(ROUTES_NID));
+ break;
+ case SUBTREE_MODIFIED:
+ for (DataTreeCandidateNode modifiedRoute : ribSupport.changedRoutes(modifiedRoutes)) {
+ processRoute(tx, ribSupport, effectiveTablePath, modifiedRoute, longLivedStale);
+ }
+ break;
+ case UNMODIFIED:
+ // No-op
+ return;
+ default:
+ LOG.warn("Ignoring modified routes {}", modifiedRoutes);
+ break;
+ }
+ });
+ }
+
+ private void writeTable(final DOMDataTreeWriteTransaction tx, final RIBSupportContext ribContext,
+ final YangInstanceIdentifier effectiveTablePath, final DataTreeCandidateNode table) {
+ LOG.debug("Write Effective Table {}", effectiveTablePath);
+ onDeleteTable(ribContext.getRibSupport(), effectiveTablePath, table.getDataBefore());
+
+ final Optional<NormalizedNode<?, ?>> maybeTableAfter = table.getDataAfter();
+ if (maybeTableAfter.isPresent()) {
+ final MapEntryNode tableAfter = extractMapEntry(maybeTableAfter);
+ ribContext.createEmptyTableStructure(tx, effectiveTablePath);
+
+ final Optional<DataContainerChild<?, ?>> maybeAttrsAfter = tableAfter.getChild(ATTRIBUTES_NID);
+ final boolean longLivedStale;
+ if (maybeAttrsAfter.isPresent()) {
+ final ContainerNode attrsAfter = extractContainer(maybeAttrsAfter);
+ longLivedStale = isLongLivedStale(attrsAfter);
+ tx.put(LogicalDatastoreType.OPERATIONAL, effectiveTablePath.node(ATTRIBUTES_NID),
+ effectiveAttributes(attrsAfter.getChild(UPTODATE_NID)));
+ } else {
+ longLivedStale = false;
+ }