- LOG.trace("Received data change to LocRib {}", Arrays.toString(changes.toArray()));
- /*
- * We use two-stage processing here in hopes that we avoid duplicate
- * calculations when multiple peers have changed a particular entry.
- */
- final Map<RouteUpdateKey, RouteEntry> toUpdate = new HashMap<>();
- for (final DataTreeCandidate tc : changes) {
- printChildren(tc.getRootNode());
-
- final YangInstanceIdentifier path = tc.getRootPath();
- final PathArgument routeId = path.getLastPathArgument();
- final NodeIdentifierWithPredicates peerKey = IdentifierUtils.peerKey(path);
- final PeerId peerId = IdentifierUtils.peerId(peerKey);
- final UnsignedInteger routerId = RouterIds.routerIdForPeerId(peerId);
+ LOG.trace("Received data change {} to LocRib {}", changes, this);
+
+ final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
+ try {
+ final Map<RouteUpdateKey, RouteEntry> toUpdate = update(tx, changes);
+
+ if (!toUpdate.isEmpty()) {
+ walkThrough(tx, toUpdate.entrySet());
+ }
+ } catch (final Exception e) {
+ LOG.error("Failed to completely propagate updates {}, state is undefined", changes, e);
+ } finally {
+ tx.submit();
+ }
+ }
+
+ private Map<RouteUpdateKey, RouteEntry> update(final DOMDataWriteTransaction tx, final Collection<DataTreeCandidate> changes) {
+ final Map<RouteUpdateKey, RouteEntry> ret = new HashMap<>();
+ changes.forEach(tc -> {
+ final DataTreeCandidateNode table = tc.getRootNode();
+ final YangInstanceIdentifier rootPath = tc.getRootPath();
+ final PeerId peerId = IdentifierUtils.peerKeyToPeerId(rootPath);
+ initializeTableWithExistentRoutes(table, peerId, rootPath, tx);
+ updateNodes(table, peerId, tx, ret);
+ });
+ return ret;
+ }
+
+ private void initializeTableWithExistentRoutes(final DataTreeCandidateNode table, final PeerId peerIdOfNewPeer, final YangInstanceIdentifier rootPath,
+ final DOMDataWriteTransaction tx) {
+ if (!table.getDataBefore().isPresent() && this.exportPolicyPeerTracker.isTableSupported(peerIdOfNewPeer)) {
+ LOG.debug("Peer {} table has been created, inserting existent routes", peerIdOfNewPeer);
+ final PeerRole newPeerRole = this.exportPolicyPeerTracker.getRole(IdentifierUtils.peerPath(rootPath));
+ final PeerExportGroup peerGroup = this.exportPolicyPeerTracker.getPeerGroup(newPeerRole);
+ this.routeEntries.entrySet().forEach(entry -> entry.getValue().writeRoute(peerIdOfNewPeer, entry.getKey(),
+ rootPath.getParent().getParent().getParent(), peerGroup, this.localTablesKey, this.exportPolicyPeerTracker, this.ribSupport, tx));
+ }
+ }
+
+ private void updateNodes(final DataTreeCandidateNode table, final PeerId peerId, final DOMDataWriteTransaction tx,
+ final Map<RouteUpdateKey, RouteEntry> routes) {
+ for (final DataTreeCandidateNode child : table.getChildNodes()) {
+ LOG.debug("Modification type {}", child.getModificationType());
+ if ((Attributes.QNAME).equals(child.getIdentifier().getNodeType())) {
+ if (child.getDataAfter().isPresent()) {
+ // putting uptodate attribute in
+ LOG.trace("Uptodate found for {}", child.getDataAfter());
+ tx.put(LogicalDatastoreType.OPERATIONAL, this.locRibTarget.node(child.getIdentifier()), child.getDataAfter().get());
+ }
+ continue;
+ }
+ updateRoutesEntries(child, peerId, routes);
+ }
+ }