import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.l2switch.loopremover.util.InstanceIdentifierUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatus;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatusAwareNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2switch.loopremover.rev140714.StpStatusAwareNodeConnectorBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
/**
- * Listens to data change events on topology links
- * {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link}
+ * Listens to data change events on topology links {@link
+ * org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link}
* and maintains a topology graph using provided NetworkGraphService
* {@link org.opendaylight.l2switch.loopremover.topology.NetworkGraphService}.
- * It refreshes the graph after a delay(default 10 sec) to accommodate burst of change events if they come in bulk.
- * This is to avoid continuous refresh of graph on a series of change events in short time.
+ * It refreshes the graph after a delay(default 10 sec) to accommodate burst of
+ * change events if they come in bulk. This is to avoid continuous refresh of
+ * graph on a series of change events in short time.
*/
-public class TopologyLinkDataChangeHandler implements DataChangeListener {
- private static final Logger _logger = LoggerFactory.getLogger(TopologyLinkDataChangeHandler.class);
- private static final String DEFAULT_TOPOLOGY_ID = "flow:1";
-
- private final ExecutorService topologyDataChangeEventProcessor = Executors.newFixedThreadPool(1);
-
- private final NetworkGraphService networkGraphService;
- private final DataBroker dataBroker;
- boolean doneOnce = false;
-
- /**
- * Uses default delay to refresh topology graph if this constructor is used.
- *
- * @param dataBroker
- * @param networkGraphService
- */
- public TopologyLinkDataChangeHandler(DataBroker dataBroker, NetworkGraphService networkGraphService) {
- Preconditions.checkNotNull(dataBroker, "dataBroker should not be null.");
- Preconditions.checkNotNull(networkGraphService, "networkGraphService should not be null.");
- this.dataBroker = dataBroker;
- this.networkGraphService = networkGraphService;
- }
-
- /**
- * Registers as a data listener to receive changes done to
- * {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link}
- * under {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology}
- * operation data root.
- */
-
- public ListenerRegistration<DataChangeListener> registerAsDataChangeListener() {
- InstanceIdentifier<Link> linkInstance = InstanceIdentifier.builder(NetworkTopology.class)
- .child(Topology.class, new TopologyKey(new TopologyId(DEFAULT_TOPOLOGY_ID))).child(Link.class).toInstance();
- return dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, linkInstance, this, AsyncDataBroker.DataChangeScope.BASE);
- }
-
- @Override
- public void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> instanceIdentifierDataObjectAsyncDataChangeEvent) {
- if(instanceIdentifierDataObjectAsyncDataChangeEvent == null) {
- return;
+public class TopologyLinkDataChangeHandler implements DataTreeChangeListener<Link> {
+ private static final Logger LOG = LoggerFactory.getLogger(TopologyLinkDataChangeHandler.class);
+ private static final String DEFAULT_TOPOLOGY_ID = "flow:1";
+ private static final long DEFAULT_GRAPH_REFRESH_DELAY = 1000;
+
+ private final ScheduledExecutorService topologyDataChangeEventProcessor = Executors.newScheduledThreadPool(1);
+
+ private final NetworkGraphService networkGraphService;
+ private volatile boolean networkGraphRefreshScheduled = false;
+ private volatile boolean threadReschedule = false;
+ private long graphRefreshDelay;
+ private String topologyId;
+
+ private final DataBroker dataBroker;
+
+ public TopologyLinkDataChangeHandler(DataBroker dataBroker, NetworkGraphService networkGraphService) {
+ Preconditions.checkNotNull(dataBroker, "dataBroker should not be null.");
+ Preconditions.checkNotNull(networkGraphService, "networkGraphService should not be null.");
+ this.dataBroker = dataBroker;
+ this.networkGraphService = networkGraphService;
}
- topologyDataChangeEventProcessor.submit(new TopologyDataChangeEventProcessor(instanceIdentifierDataObjectAsyncDataChangeEvent));
- _logger.info("************After topologyDataChangeEventProcessor called ");
- }
-
- /**
- *
- */
- private class TopologyDataChangeEventProcessor implements Runnable {
- AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> instanceIdentifierDataObjectAsyncDataChangeEvent;
-
-
- public TopologyDataChangeEventProcessor(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> dataChangeEvent) {
- this.instanceIdentifierDataObjectAsyncDataChangeEvent = dataChangeEvent;
- }
-
- @Override
- public void run() {
-
- if(instanceIdentifierDataObjectAsyncDataChangeEvent == null) {
- return;
- }
- Map<InstanceIdentifier<?>, DataObject> createdData = instanceIdentifierDataObjectAsyncDataChangeEvent.getCreatedData();
- Set<InstanceIdentifier<?>> removedPaths = instanceIdentifierDataObjectAsyncDataChangeEvent.getRemovedPaths();
- Map<InstanceIdentifier<?>, DataObject> originalData = instanceIdentifierDataObjectAsyncDataChangeEvent.getOriginalData();
- boolean isGraphUpdated = false;
- ReadWriteTransaction readWriteTransaction = null;
-
- _logger.info("Topology Event Started********************** ");
- if(createdData != null && !createdData.isEmpty()) {
- List<Link> links = new ArrayList<>();
- for(InstanceIdentifier<?> instanceId : createdData.keySet()) {
- if(Link.class.isAssignableFrom(instanceId.getTargetType())) {
- links.add((Link) createdData.get(instanceId));
- }
- }
- if(!links.isEmpty()) {
- networkGraphService.addLinks(links);
- isGraphUpdated = true;
- }
- }
-
- List<Link> removedLinks = null;
- if(removedPaths != null && !removedPaths.isEmpty() && originalData != null && !originalData.isEmpty()) {
- removedLinks = new ArrayList<>();
- for(InstanceIdentifier<?> instanceId : removedPaths) {
- if(Link.class.isAssignableFrom(instanceId.getTargetType())) {
- Link link = (Link) originalData.get(instanceId);
- removedLinks.add(link);
- }
- }
- if(!removedLinks.isEmpty()) {
- networkGraphService.removeLinks(removedLinks);
- isGraphUpdated = true;
- }
- }
-
- if(isGraphUpdated) {
- readWriteTransaction = dataBroker.newReadWriteTransaction();
- if(removedLinks != null && !removedLinks.isEmpty()) {
- for(Link link : removedLinks) {
- updateNodeConnector(readWriteTransaction, getSourceNodeConnectorRef(link), StpStatus.Discarding);
- updateNodeConnector(readWriteTransaction, getDestNodeConnectorRef(link), StpStatus.Discarding);
- }
+ public void setGraphRefreshDelay(long graphRefreshDelay) {
+ if (graphRefreshDelay < 0) {
+ this.graphRefreshDelay = DEFAULT_GRAPH_REFRESH_DELAY;
+ } else {
+ this.graphRefreshDelay = graphRefreshDelay;
}
- updateNodeConnectorStatus(readWriteTransaction);
- readWriteTransaction.commit();
- }
}
- /**
- * @param readWriteTransaction
- */
- private void updateNodeConnectorStatus(ReadWriteTransaction readWriteTransaction) {
- List<Link> allLinks = networkGraphService.getAllLinks();
- if(allLinks == null || allLinks.isEmpty()) {
- return;
- }
-
- List<Link> mstLinks = networkGraphService.getLinksInMst();
- for(Link link : allLinks) {
- if(mstLinks != null && !mstLinks.isEmpty() && mstLinks.contains(link)) {
- updateNodeConnector(readWriteTransaction, getSourceNodeConnectorRef(link), StpStatus.Forwarding);
- updateNodeConnector(readWriteTransaction, getDestNodeConnectorRef(link), StpStatus.Forwarding);
+ public void setTopologyId(String topologyId) {
+ if (topologyId == null || topologyId.isEmpty()) {
+ this.topologyId = DEFAULT_TOPOLOGY_ID;
} else {
- updateNodeConnector(readWriteTransaction, getSourceNodeConnectorRef(link), StpStatus.Discarding);
- updateNodeConnector(readWriteTransaction, getDestNodeConnectorRef(link), StpStatus.Discarding);
+ this.topologyId = topologyId;
}
- }
}
/**
- * @param link
- * @return
+ * Registers as a data listener to receive changes done to {@link org.opendaylight.yang.gen.v1.urn.tbd.params
+ * .xml.ns.yang.network.topology.rev131021.network.topology.topology.Link}
+ * under
+ * {@link org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology}
+ * operation data root.
*/
- private NodeConnectorRef getSourceNodeConnectorRef(Link link) {
- InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier
- = InstanceIdentifierUtils.createNodeConnectorIdentifier(
- link.getSource().getSourceNode().getValue(),
- link.getSource().getSourceTp().getValue());
- return new NodeConnectorRef(nodeConnectorInstanceIdentifier);
+ public ListenerRegistration<TopologyLinkDataChangeHandler> registerAsDataChangeListener() {
+ InstanceIdentifier<Link> linkInstance = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(topologyId))).child(Link.class).build();
+ return dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
+ LogicalDatastoreType.OPERATIONAL, linkInstance), this);
}
/**
- * @param link
- * @return
+ * Handler for onDataChanged events and schedules the building of the
+ * network graph.
*/
- private NodeConnectorRef getDestNodeConnectorRef(Link link) {
- InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier
- = InstanceIdentifierUtils.createNodeConnectorIdentifier(
- link.getDestination().getDestNode().getValue(),
- link.getDestination().getDestTp().getValue());
-
- return new NodeConnectorRef(nodeConnectorInstanceIdentifier);
- }
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<Link>> changes) {
+ boolean isGraphUpdated = false;
+
+ for (DataTreeModification<Link> change: changes) {
+ DataObjectModification<Link> rootNode = change.getRootNode();
+ switch (rootNode.getModificationType()) {
+ case WRITE:
+ Link createdLink = rootNode.getDataAfter();
+ if (rootNode.getDataBefore() == null && !createdLink.getLinkId().getValue().contains("host")) {
+ isGraphUpdated = true;
+ LOG.debug("Graph is updated! Added Link {}", createdLink.getLinkId().getValue());
+ }
+ break;
+ case DELETE:
+ Link deletedLink = rootNode.getDataBefore();
+ if (!deletedLink.getLinkId().getValue().contains("host")) {
+ isGraphUpdated = true;
+ LOG.debug("Graph is updated! Removed Link {}", deletedLink.getLinkId().getValue());
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- /**
- * @param readWriteTransaction
- * @param nodeConnectorRef
- * @param stpStatus
- */
- private void updateNodeConnector(ReadWriteTransaction readWriteTransaction, NodeConnectorRef nodeConnectorRef, StpStatus stpStatus) {
- StpStatusAwareNodeConnectorBuilder stpStatusAwareNodeConnectorBuilder = new StpStatusAwareNodeConnectorBuilder()
- .setStatus(stpStatus);
- checkIfExistAndUpdateNodeConnector(readWriteTransaction, nodeConnectorRef, stpStatusAwareNodeConnectorBuilder.build());
+ if (!isGraphUpdated) {
+ return;
+ }
+ if (!networkGraphRefreshScheduled) {
+ synchronized (this) {
+ if (!networkGraphRefreshScheduled) {
+ topologyDataChangeEventProcessor.schedule(new TopologyDataChangeEventProcessor(), graphRefreshDelay,
+ TimeUnit.MILLISECONDS);
+ networkGraphRefreshScheduled = true;
+ LOG.debug("Scheduled Graph for refresh.");
+ }
+ }
+ } else {
+ LOG.debug("Already scheduled for network graph refresh.");
+ threadReschedule = true;
+ }
}
- /**
- * @param readWriteTransaction
- * @param nodeConnectorRef
- * @param stpStatusAwareNodeConnector
- */
- private void checkIfExistAndUpdateNodeConnector(ReadWriteTransaction readWriteTransaction, NodeConnectorRef nodeConnectorRef, StpStatusAwareNodeConnector stpStatusAwareNodeConnector) {
- NodeConnector nc = null;
- try {
- Optional<DataObject> dataObjectOptional = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, nodeConnectorRef.getValue()).get();
- if(dataObjectOptional.isPresent())
- nc = (NodeConnector) dataObjectOptional.get();
- } catch(Exception e) {
- _logger.error("Error reading node connector {}", nodeConnectorRef.getValue());
- readWriteTransaction.commit();
- throw new RuntimeException("Error reading from configuration store, node connector : " + nodeConnectorRef, e);
- }
- NodeConnectorBuilder nodeConnectorBuilder;
- if(nc != null) {
- if(sameStatusPresent(nc.getAugmentation(StpStatusAwareNodeConnector.class), stpStatusAwareNodeConnector.getStatus())) {
- return;
+ private class TopologyDataChangeEventProcessor implements Runnable {
+
+ @Override
+ public void run() {
+ if (threadReschedule) {
+ topologyDataChangeEventProcessor.schedule(this, graphRefreshDelay, TimeUnit.MILLISECONDS);
+ threadReschedule = false;
+ return;
+ }
+ LOG.debug("In network graph refresh thread.");
+ networkGraphRefreshScheduled = false;
+ networkGraphService.clear();
+ List<Link> links = getLinksFromTopology();
+ if (links == null || links.isEmpty()) {
+ return;
+ }
+ networkGraphService.addLinks(links);
+ final ReadWriteTransaction readWriteTransaction = dataBroker.newReadWriteTransaction();
+ updateNodeConnectorStatus(readWriteTransaction);
+ Futures.addCallback(readWriteTransaction.submit(), new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void notUsed) {
+ LOG.debug("TopologyLinkDataChangeHandler write successful for tx :{}",
+ readWriteTransaction.getIdentifier());
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ LOG.error("TopologyLinkDataChangeHandler write transaction {} failed",
+ readWriteTransaction.getIdentifier(), throwable.getCause());
+ }
+ }, MoreExecutors.directExecutor());
+ LOG.debug("Done with network graph refresh thread.");
}
- nodeConnectorBuilder = new NodeConnectorBuilder(nc)
- .setKey(nc.getKey())
- .addAugmentation(StpStatusAwareNodeConnector.class, stpStatusAwareNodeConnector);
- readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, nodeConnectorRef.getValue(), nodeConnectorBuilder.build());
- _logger.info("Updated node connector in configuration {}", nodeConnectorRef);
- } else {
- NodeConnectorKey nodeConnectorKey = InstanceIdentifierUtils.getNodeConnectorKey(nodeConnectorRef.getValue());
- nodeConnectorBuilder = new NodeConnectorBuilder()
- .setKey(nodeConnectorKey)
- .setId(nodeConnectorKey.getId())
- .addAugmentation(StpStatusAwareNodeConnector.class, stpStatusAwareNodeConnector);
- nc = nodeConnectorBuilder.build();
- checkIfExistAndUpdateNode(readWriteTransaction, nodeConnectorRef, nc);
- }
- }
+ private List<Link> getLinksFromTopology() {
+ InstanceIdentifier<Topology> topologyInstanceIdentifier = InstanceIdentifierUtils
+ .generateTopologyInstanceIdentifier(topologyId);
+ Topology topology = null;
+ ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();
+ try {
+ Optional<Topology> topologyOptional = readOnlyTransaction
+ .read(LogicalDatastoreType.OPERATIONAL, topologyInstanceIdentifier).get();
+ if (topologyOptional.isPresent()) {
+ topology = topologyOptional.get();
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Error reading topology {}", topologyInstanceIdentifier);
+ readOnlyTransaction.close();
+ throw new RuntimeException(
+ "Error reading from operational store, topology : " + topologyInstanceIdentifier, e);
+ }
+ readOnlyTransaction.close();
+ if (topology == null) {
+ return null;
+ }
+ List<Link> links = topology.getLink();
+ if (links == null || links.isEmpty()) {
+ return null;
+ }
+ List<Link> internalLinks = new ArrayList<>();
+ for (Link link : links) {
+ if (!link.getLinkId().getValue().contains("host")) {
+ internalLinks.add(link);
+ }
+ }
+ return internalLinks;
+ }
- /**
- * @param stpStatusAwareNodeConnector
- * @return
- */
- private boolean sameStatusPresent(StpStatusAwareNodeConnector stpStatusAwareNodeConnector, StpStatus stpStatus) {
+ private void updateNodeConnectorStatus(ReadWriteTransaction readWriteTransaction) {
+ List<Link> allLinks = networkGraphService.getAllLinks();
+ if (allLinks == null || allLinks.isEmpty()) {
+ return;
+ }
+
+ List<Link> mstLinks = networkGraphService.getLinksInMst();
+ for (Link link : allLinks) {
+ if (mstLinks != null && !mstLinks.isEmpty() && mstLinks.contains(link)) {
+ updateNodeConnector(readWriteTransaction, getSourceNodeConnectorRef(link), StpStatus.Forwarding);
+ updateNodeConnector(readWriteTransaction, getDestNodeConnectorRef(link), StpStatus.Forwarding);
+ } else {
+ updateNodeConnector(readWriteTransaction, getSourceNodeConnectorRef(link), StpStatus.Discarding);
+ updateNodeConnector(readWriteTransaction, getDestNodeConnectorRef(link), StpStatus.Discarding);
+ }
+ }
+ }
- if(stpStatusAwareNodeConnector == null)
- return false;
+ private NodeConnectorRef getSourceNodeConnectorRef(Link link) {
+ InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier = InstanceIdentifierUtils
+ .createNodeConnectorIdentifier(link.getSource().getSourceNode().getValue(),
+ link.getSource().getSourceTp().getValue());
+ return new NodeConnectorRef(nodeConnectorInstanceIdentifier);
+ }
- if(stpStatusAwareNodeConnector.getStatus() == null)
- return false;
+ private NodeConnectorRef getDestNodeConnectorRef(Link link) {
+ InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier = InstanceIdentifierUtils
+ .createNodeConnectorIdentifier(link.getDestination().getDestNode().getValue(),
+ link.getDestination().getDestTp().getValue());
- if(stpStatus.getIntValue() != stpStatusAwareNodeConnector.getStatus().getIntValue())
- return false;
+ return new NodeConnectorRef(nodeConnectorInstanceIdentifier);
+ }
- return true;
- }
+ private void updateNodeConnector(ReadWriteTransaction readWriteTransaction, NodeConnectorRef nodeConnectorRef,
+ StpStatus stpStatus) {
+ StpStatusAwareNodeConnectorBuilder stpStatusAwareNodeConnectorBuilder =
+ new StpStatusAwareNodeConnectorBuilder().setStatus(stpStatus);
+ checkIfExistAndUpdateNodeConnector(readWriteTransaction, nodeConnectorRef,
+ stpStatusAwareNodeConnectorBuilder.build());
+ }
- /**
- * @param readWriteTransaction
- * @param nodeConnectorRef
- * @param nc
- */
- private void checkIfExistAndUpdateNode(ReadWriteTransaction readWriteTransaction, NodeConnectorRef nodeConnectorRef, NodeConnector nc) {
- Node node = null;
- InstanceIdentifier<Node> nodeInstanceIdentifier = InstanceIdentifierUtils.generateNodeInstanceIdentifier(nodeConnectorRef);
- try {
- Optional<DataObject> dataObjectOptional = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, nodeInstanceIdentifier).get();
- if(dataObjectOptional.isPresent())
- node = (Node) dataObjectOptional.get();
- } catch(Exception e) {
- _logger.error("Error reading node {}", nodeInstanceIdentifier);
- readWriteTransaction.commit();
- throw new RuntimeException("Error reading from configuration store, node : " + nodeInstanceIdentifier, e);
- }
- if(node != null) {
- List<NodeConnector> nodeConnectors = node.getNodeConnector();
- if(nodeConnectors == null) {
- nodeConnectors = new ArrayList<>();
+ private void checkIfExistAndUpdateNodeConnector(ReadWriteTransaction readWriteTransaction,
+ NodeConnectorRef nodeConnectorRef, StpStatusAwareNodeConnector stpStatusAwareNodeConnector) {
+ NodeConnector nc = null;
+ try {
+ Optional<NodeConnector> dataObjectOptional = readWriteTransaction.read(LogicalDatastoreType.OPERATIONAL,
+ (InstanceIdentifier<NodeConnector>) nodeConnectorRef.getValue()).get();
+ if (dataObjectOptional.isPresent()) {
+ nc = dataObjectOptional.get();
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Error reading node connector {}", nodeConnectorRef.getValue());
+ readWriteTransaction.submit();
+ throw new RuntimeException("Error reading from operational store, node connector : " + nodeConnectorRef,
+ e);
+ }
+
+ if (nc != null) {
+ if (sameStatusPresent(nc.getAugmentation(StpStatusAwareNodeConnector.class),
+ stpStatusAwareNodeConnector.getStatus())) {
+ return;
+ }
+
+ // build instance id for StpStatusAwareNodeConnector
+ InstanceIdentifier<StpStatusAwareNodeConnector> stpStatusAwareNcInstanceId =
+ ((InstanceIdentifier<NodeConnector>) nodeConnectorRef
+ .getValue()).augmentation(StpStatusAwareNodeConnector.class);
+ // update StpStatusAwareNodeConnector in operational store
+ readWriteTransaction.merge(LogicalDatastoreType.OPERATIONAL, stpStatusAwareNcInstanceId,
+ stpStatusAwareNodeConnector);
+ LOG.debug("Merged Stp Status aware node connector in operational {} with status {}",
+ stpStatusAwareNcInstanceId, stpStatusAwareNodeConnector);
+ } else {
+ LOG.error("Unable to update Stp Status node connector {} note present in operational store",
+ nodeConnectorRef.getValue());
+ }
}
- nodeConnectors.add(nc);
- NodeBuilder nodeBuilder = new NodeBuilder(node)
- .setNodeConnector(nodeConnectors);
- node = nodeBuilder.build();
- readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceIdentifier, node);
- _logger.info("Updated node {} in configuration store with node id {}", node, nodeInstanceIdentifier);
- } else {
- NodeKey nodeKey = nodeConnectorRef.getValue().firstKeyOf(Node.class, NodeKey.class);
- List<NodeConnector> nodeConnectors = new ArrayList<>();
- nodeConnectors.add(nc);
- NodeBuilder nodeBuilder = new NodeBuilder()
- .setKey(nodeKey)
- .setId(nodeKey.getId())
- .setNodeConnector(nodeConnectors);
- node = nodeBuilder.build();
- checkIfExistsAndUpdateNodes(readWriteTransaction, nodeConnectorRef, node);
- }
- }
+ private boolean sameStatusPresent(StpStatusAwareNodeConnector stpStatusAwareNodeConnector,
+ StpStatus stpStatus) {
- /**
- * @param readWriteTransaction
- * @param nodeConnectorRef
- * @param node
- */
- private void checkIfExistsAndUpdateNodes(ReadWriteTransaction readWriteTransaction, NodeConnectorRef nodeConnectorRef, Node node) {
+ if (stpStatusAwareNodeConnector == null) {
+ return false;
+ }
+
+ if (stpStatusAwareNodeConnector.getStatus() == null) {
+ return false;
+ }
- List<Node> nodesList = null;
+ if (stpStatus.getIntValue() != stpStatusAwareNodeConnector.getStatus().getIntValue()) {
+ return false;
+ }
- Nodes nodes = null;
- InstanceIdentifier<Nodes> nodesInstanceIdentifier = nodeConnectorRef.getValue().firstIdentifierOf(Nodes.class);
- try {
- Optional<DataObject> dataObjectOptional = readWriteTransaction.read(LogicalDatastoreType.CONFIGURATION, nodesInstanceIdentifier).get();
- if(dataObjectOptional.isPresent())
- nodes = (Nodes) dataObjectOptional.get();
- } catch(Exception e) {
- _logger.error("Error reading nodes {}", nodesInstanceIdentifier);
- readWriteTransaction.commit();
- throw new RuntimeException("Error reading from configuration store, nodes : " + nodesInstanceIdentifier, e);
- }
- if(nodes != null) {
- nodesList = nodes.getNode();
- }
- if(nodesList == null) {
- nodesList = new ArrayList<>();
- }
- nodesList.add(node);
- NodesBuilder nodesBuilder = new NodesBuilder()
- .setNode(nodesList);
- nodes = nodesBuilder.build();
- readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, nodesInstanceIdentifier, nodes);
- _logger.info("Updated nodes {} in configuration store with nodes id {}", nodes, nodesInstanceIdentifier);
+ return true;
+ }
}
- }
}