Add K-shortest path API to PathService.

Change-Id: I96732666f31a7a2b2df9a16f63e77bc0a367da83
diff --git a/core/api/src/main/java/org/onosproject/net/topology/AbstractPathService.java b/core/api/src/main/java/org/onosproject/net/topology/AbstractPathService.java
index 2c43fc7..35b9fce 100644
--- a/core/api/src/main/java/org/onosproject/net/topology/AbstractPathService.java
+++ b/core/api/src/main/java/org/onosproject/net/topology/AbstractPathService.java
@@ -39,6 +39,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.net.topology.AdapterLinkWeigher.adapt;
@@ -105,6 +106,40 @@
     }
 
     @Override
+    public Stream<Path> getKShortestPaths(ElementId src, ElementId dst,
+                                          LinkWeigher weigher) {
+        checkNotNull(src, ELEMENT_ID_NULL);
+        checkNotNull(dst, ELEMENT_ID_NULL);
+
+        LinkWeigher internalWeigher = weigher != null ? weigher : DEFAULT_WEIGHER;
+
+        // Get the source and destination edge locations
+        EdgeLink srcEdge = getEdgeLink(src, true);
+        EdgeLink dstEdge = getEdgeLink(dst, false);
+
+        // If either edge is null, bail with no paths.
+        if (srcEdge == null || dstEdge == null) {
+            return Stream.empty();
+        }
+
+        DeviceId srcDevice = srcEdge != NOT_HOST ? srcEdge.dst().deviceId() : (DeviceId) src;
+        DeviceId dstDevice = dstEdge != NOT_HOST ? dstEdge.src().deviceId() : (DeviceId) dst;
+
+        // If the source and destination are on the same edge device, there
+        // is just one path, so build it and return it.
+        if (srcDevice.equals(dstDevice)) {
+            return Stream.of(edgeToEdgePath(srcEdge, dstEdge, null, internalWeigher));
+        }
+
+        // Otherwise get all paths between the source and destination edge
+        // devices.
+        Topology topology = topologyService.currentTopology();
+
+        return topologyService.getKShortestPaths(topology, srcDevice, dstDevice, internalWeigher)
+                .map(path -> edgeToEdgePath(srcEdge, dstEdge, path, internalWeigher));
+    }
+
+    @Override
     public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) {
         return getDisjointPaths(src, dst, adapt(weight));
     }