2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.l2switch.loopremover.topology;
10 import com.google.common.base.Preconditions;
11 import edu.uci.ics.jung.algorithms.shortestpath.PrimMinimumSpanningTree;
12 import edu.uci.ics.jung.graph.DelegateTree;
13 import edu.uci.ics.jung.graph.Graph;
14 import edu.uci.ics.jung.graph.SparseMultigraph;
15 import edu.uci.ics.jung.graph.util.EdgeType;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.HashSet;
19 import java.util.List;
21 import javax.annotation.concurrent.GuardedBy;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Implementation of NetworkGraphService
29 * {@link org.opendaylight.l2switch.loopremover.topology.NetworkGraphService}. It
30 * uses Jung graph library internally to maintain a graph and optimum way to
31 * return shortest path using Dijkstra algorithm.
33 public class NetworkGraphImpl implements NetworkGraphService {
35 private static final Logger LOG = LoggerFactory.getLogger(NetworkGraphImpl.class);
38 private Graph<NodeId, Link> networkGraph;
39 private final Set<String> linkAdded = new HashSet<>();
41 // Enable following lines when shortest path functionality is required.
42 // DijkstraShortestPath<NodeId, Link> shortestPath = null;
45 * Adds links to existing graph or creates new directed graph with given
46 * links if graph was not initialized.
52 public synchronized void addLinks(List<Link> links) {
53 if (links == null || links.isEmpty()) {
54 LOG.info("In addLinks: No link added as links is null or empty.");
58 if (networkGraph == null) {
59 networkGraph = SparseMultigraph.<NodeId, Link>getFactory().get();
62 for (Link link : links) {
63 if (linkAlreadyAdded(link)) {
66 NodeId sourceNodeId = link.getSource().getSourceNode();
67 NodeId destinationNodeId = link.getDestination().getDestNode();
68 networkGraph.addVertex(sourceNodeId);
69 networkGraph.addVertex(destinationNodeId);
70 networkGraph.addEdge(link, sourceNodeId, destinationNodeId, EdgeType.UNDIRECTED);
74 * if(shortestPath == null) { shortestPath = new
75 * DijkstraShortestPath<>(networkGraph); } else { shortestPath.reset();
81 private boolean linkAlreadyAdded(Link link) {
82 String linkAddedKey = null;
83 if (link.getDestination().getDestTp().hashCode() > link.getSource().getSourceTp().hashCode()) {
84 linkAddedKey = link.getSource().getSourceTp().getValue() + link.getDestination().getDestTp().getValue();
86 linkAddedKey = link.getDestination().getDestTp().getValue() + link.getSource().getSourceTp().getValue();
88 if (linkAdded.contains(linkAddedKey)) {
91 linkAdded.add(linkAddedKey);
97 * Removes links from existing graph.
100 * The links to remove.
103 public synchronized void removeLinks(List<Link> links) {
104 Preconditions.checkNotNull(networkGraph, "Graph is not initialized, add links first.");
106 if (links == null || links.isEmpty()) {
107 LOG.info("In removeLinks: No link removed as links is null or empty.");
111 for (Link link : links) {
112 networkGraph.removeEdge(link);
115 * if(shortestPath == null) { shortestPath = new
116 * DijkstraShortestPath<>(networkGraph); } else { shortestPath.reset();
123 * returns a path between 2 nodes. Uses Dijkstra's algorithm to return
126 * @param sourceNodeId the source node Id
127 * @param destinationNodeId the destination node Id
131 * public synchronized List<Link> getPath(NodeId sourceNodeId, NodeId
132 * destinationNodeId) { Preconditions.checkNotNull(shortestPath,
133 * "Graph is not initialized, add links first.");
135 * if(sourceNodeId == null || destinationNodeId == null) { _logger.info(
136 * "In getPath: returning null, as sourceNodeId or destinationNodeId is null."
139 * return shortestPath.getPath(sourceNodeId, destinationNodeId); }
143 * Clears the prebuilt graph, in case same service instance is required to
144 * process a new graph.
147 public synchronized void clear() {
150 // shortestPath = null;
154 * Forms MST(minimum spanning tree) from network graph and returns links
155 * that are not in MST.
157 * @return The links in the MST (minimum spanning tree)
160 public synchronized List<Link> getLinksInMst() {
161 List<Link> linksInMst = new ArrayList<>();
162 if (networkGraph != null) {
163 PrimMinimumSpanningTree<NodeId, Link> networkMst = new PrimMinimumSpanningTree<>(
164 DelegateTree.<NodeId, Link>getFactory());
165 Graph<NodeId, Link> mstGraph = networkMst.apply(networkGraph);
166 Collection<Link> mstLinks = mstGraph.getEdges();
167 linksInMst.addAll(mstLinks);
173 * Get all the links in the network.
175 * @return The links in the network.
178 public synchronized List<Link> getAllLinks() {
179 List<Link> allLinks = new ArrayList<>();
180 if (networkGraph != null) {
181 allLinks.addAll(networkGraph.getEdges());