Disjoint Path Utils Exposed

- to TopologyStores
- to TopologyServices
- to PathServices
- to REST API

Change-Id: Ib2b5840df0f8e94f327ec8f91827d3d850634562

Change-Id: I03e59210e9c79c4f92dcfa8c7983642572708429

Change-Id: Ia5c17d1ded374ef688990bd30e7f99184aaca95b

Change-Id: Ibebae50bc722701e8212263587727ad8abd79805
diff --git a/core/api/src/main/java/org/onosproject/net/topology/PathService.java b/core/api/src/main/java/org/onosproject/net/topology/PathService.java
index be8c7cf..d41b4ee 100644
--- a/core/api/src/main/java/org/onosproject/net/topology/PathService.java
+++ b/core/api/src/main/java/org/onosproject/net/topology/PathService.java
@@ -15,9 +15,12 @@
  */
 package org.onosproject.net.topology;
 
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.ElementId;
+import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -48,4 +51,51 @@
      */
     Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight);
 
+    /**
+     * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
+     * between the specified source and destination devices.
+     *
+     * @param src      source device
+     * @param dst      destination device
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst);
+
+    /**
+     * Returns the set of all disjoint shortest path pairs, computed using the supplied
+     * edge-weight entity, between the specified source and destination devices.
+     *
+     * @param src      source device
+     * @param dst      destination device
+     * @param weight   edge-weight entity
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
+                                       LinkWeight weight);
+
+    /**
+     * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
+     * between the specified source and destination devices.
+     *
+     * @param src      source device
+     * @param dst      destination device
+     * @param riskProfile map of edges to risk profiles
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst,
+                                           Map<Link, Object> riskProfile);
+
+    /**
+     * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
+     * between the specified source and destination devices.
+     *
+     * @param src      source device
+     * @param dst      destination device
+     * @param weight    edge-weight entity
+     * @param riskProfile map of edges to risk profiles
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst,
+                                           LinkWeight weight, Map<Link, Object> riskProfile);
+
 }
diff --git a/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java b/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java
index 41eac2c..7b22a36 100644
--- a/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java
+++ b/core/api/src/main/java/org/onosproject/net/topology/TopologyService.java
@@ -18,9 +18,11 @@
 import org.onosproject.event.ListenerService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -112,6 +114,56 @@
                        LinkWeight weight);
 
     /**
+     * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
+     * between the specified source and destination devices.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst);
+
+    /**
+     * Returns the set of all disjoint shortest path pairs, computed using the supplied
+     * edge-weight entity, between the specified source and destination devices.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @param weight   edge-weight entity
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                       LinkWeight weight);
+
+    /**
+     * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
+     * between the specified source and destination devices.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @param riskProfile map of edges to risk profiles
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                           Map<Link, Object> riskProfile);
+
+    /**
+     * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count,
+     * between the specified source and destination devices.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @param weight    edge-weight entity
+     * @param riskProfile map of edges to risk profiles
+     * @return set of all shortest paths between the two devices
+     */
+    Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                           LinkWeight weight, Map<Link, Object> riskProfile);
+    /**
      * Indicates whether the specified connection point is part of the network
      * infrastructure or part of network edge.
      *
diff --git a/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java b/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java
index 983e616..f194878 100644
--- a/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java
+++ b/core/api/src/main/java/org/onosproject/net/topology/TopologyStore.java
@@ -20,11 +20,13 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.store.Store;
 
 import java.util.List;
 import java.util.Set;
+import java.util.Map;
 
 /**
  * Manages inventory of topology snapshots; not intended for direct use.
@@ -112,6 +114,59 @@
                        LinkWeight weight);
 
     /**
+     * Computes and returns the set of disjoint shortest path pairs
+     * between src and dst.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @param weight   link weight function
+     * @return set of shortest paths
+     */
+    Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                       LinkWeight weight);
+
+    /**
+     * Computes and returns the set of disjoint shortest path pairs
+     * between src and dst.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @return set of shortest paths
+     */
+    Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst);
+
+    /**
+     * Computes and returns the set of SRLG disjoint shortest path pairs between source
+     * and dst, given a mapping of edges to SRLG risk groups.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @param weight   link weight function
+     * @param riskProfile   map of edges to objects. Edges that map to the same object will
+     * be treated as if they were in the same risk group.
+     * @return set of shortest paths
+     */
+    Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                           LinkWeight weight, Map<Link, Object> riskProfile);
+
+    /**
+     * Returns the set of pre-computed SRLG shortest paths between src and dest.
+     *
+     * @param topology topology descriptor
+     * @param src      source device
+     * @param dst      destination device
+     * @param riskProfile   map of edges to objects. Edges that map to the same object will
+     * be treated as if they were in the same risk group.
+     * @return set of shortest paths
+     */
+    Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                           Map<Link, Object> riskProfile);
+
+
+    /**
      * Indicates whether the given connect point is part of the network fabric.
      *
      * @param topology     topology descriptor
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index ac4ecff..8d30551 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -22,6 +22,7 @@
 import org.onosproject.core.DefaultGroupId;
 import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.ElementId;
 import org.onosproject.net.Link;
 import org.onosproject.net.NetTestTools;
@@ -64,6 +65,7 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
@@ -185,6 +187,28 @@
             }
             return paths;
         }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst,
+                                                      Map<Link, Object> riskProfile) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst, LinkWeight weight,
+                                                      Map<Link, Object> riskProfile) {
+            return null;
+        }
     }
 
     public static class MockLinkResourceAllocations implements LinkResourceAllocations {
@@ -424,7 +448,7 @@
             }
             final MockFlowRule other = (MockFlowRule) obj;
             return Objects.equals(this.timestamp, other.timestamp) &&
-                   this.id == other.id;
+                    this.id == other.id;
         }
 
         @Override
@@ -450,7 +474,7 @@
 
         public MockIntent(Long number) {
             super(NetTestTools.APP_ID, null, Collections.emptyList(),
-                    Intent.DEFAULT_INTENT_PRIORITY);
+                  Intent.DEFAULT_INTENT_PRIORITY);
             this.number = number;
         }
 
diff --git a/core/api/src/test/java/org/onosproject/net/topology/TopologyServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/topology/TopologyServiceAdapter.java
index 07e6784..b5b3056 100644
--- a/core/api/src/test/java/org/onosproject/net/topology/TopologyServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/topology/TopologyServiceAdapter.java
@@ -17,9 +17,11 @@
 
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -88,5 +90,26 @@
     @Override
     public void removeListener(TopologyListener listener) {
     }
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) {
+        return null;
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
+        return null;
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                  Map<Link, Object> riskProfile) {
+        return null;
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight,
+                                                  Map<Link, Object> riskProfile) {
+        return null;
+    }
 
 }
diff --git a/core/common/src/main/java/org/onosproject/common/DefaultTopology.java b/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
index 08b5245..f2f86ea 100644
--- a/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
+++ b/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
@@ -322,8 +322,9 @@
         }
         return builder.build();
     }
+
     /**
-     /**
+     * /**
      * Returns the set of pre-computed shortest disjoint path pairs between source and
      * destination devices.
      *
@@ -331,7 +332,7 @@
      * @param dst destination device
      * @return set of shortest disjoint path pairs
      */
-    Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) {
+    public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) {
         return getDisjointPaths(src, dst, null);
     }
 
@@ -344,7 +345,7 @@
      * @param weight link weight function
      * @return set of disjoint shortest path pairs
      */
-    Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
+    public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
         final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
         final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
         Set<TopologyVertex> vertices = graph.getVertexes();
@@ -366,12 +367,12 @@
      * Computes on-demand the set of shortest disjoint risk groups path pairs between source and
      * destination devices.
      *
-     * @param src           source device
-     * @param dst           destination device
-     * @param riskProfile   map representing risk groups for each edge
-     * @return  set of shortest disjoint paths
+     * @param src         source device
+     * @param dst         destination device
+     * @param riskProfile map representing risk groups for each edge
+     * @return set of shortest disjoint paths
      */
-    Set<DisjointPath> getSRLGDisjointPathsD(DeviceId src, DeviceId dst, Map<TopologyEdge, Object> riskProfile) {
+    public Set<DisjointPath> getSRLGDisjointPathsD(DeviceId src, DeviceId dst, Map<TopologyEdge, Object> riskProfile) {
         return getSRLGDisjointPathsD(src, dst, null, riskProfile);
     }
 
@@ -379,13 +380,13 @@
      * Computes on-demand the set of shortest disjoint risk groups path pairs between source and
      * destination devices.
      *
-     * @param src       source device
-     * @param dst       destination device
-     * @param weight    edge weight object
-     * @param riskProfile   map representing risk groups for each edge
+     * @param src         source device
+     * @param dst         destination device
+     * @param weight      edge weight object
+     * @param riskProfile map representing risk groups for each edge
      * @return set of shortest disjoint paths
      */
-    Set<DisjointPath> getSRLGDisjointPathsD(DeviceId src, DeviceId dst, LinkWeight weight, Map<TopologyEdge,
+    public Set<DisjointPath> getSRLGDisjointPathsD(DeviceId src, DeviceId dst, LinkWeight weight, Map<TopologyEdge,
             Object> riskProfile) {
         final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
         final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
@@ -409,14 +410,14 @@
      * Computes on-demand the set of shortest disjoint risk groups path pairs between source and
      * destination devices.
      *
-     * @param src       source device
-     * @param dst       destination device
-     * @param weight    edge weight object
-     * @param riskProfile   map representing risk groups for each link
+     * @param src         source device
+     * @param dst         destination device
+     * @param weight      edge weight object
+     * @param riskProfile map representing risk groups for each link
      * @return set of shortest disjoint paths
      */
-    Set<DisjointPath> getSRLGDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight,
-                                           Map<Link, Object> riskProfile) {
+    public Set<DisjointPath> getSRLGDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight,
+                                                  Map<Link, Object> riskProfile) {
         Map<TopologyEdge, Object> riskProfile2 = new HashMap<>();
         for (Link l : riskProfile.keySet()) {
             riskProfile2.put(new TopologyEdge() {
@@ -450,12 +451,12 @@
      * Computes on-demand the set of shortest disjoint risk groups path pairs between source and
      * destination devices.
      *
-     * @param src       source device
-     * @param dst       destination device
-     * @param riskProfile   map representing risk groups for each link
+     * @param src         source device
+     * @param dst         destination device
+     * @param riskProfile map representing risk groups for each link
      * @return set of shortest disjoint paths
      */
-    Set<DisjointPath> getSRLGDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) {
+    public Set<DisjointPath> getSRLGDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) {
         return getSRLGDisjointPaths(src, dst, null, riskProfile);
     }
 
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java
index 6a89c01..0246d42 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleTopologyStore.java
@@ -23,6 +23,7 @@
 import org.onosproject.event.Event;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.provider.ProviderId;
@@ -39,6 +40,7 @@
 import org.slf4j.Logger;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import static org.slf4j.LoggerFactory.getLogger;
@@ -114,6 +116,29 @@
     }
 
     @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) {
+        return defaultTopology(topology).getDisjointPaths(src, dst);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                              LinkWeight weight) {
+        return defaultTopology(topology).getDisjointPaths(src, dst, weight);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                  Map<Link, Object> riskProfile) {
+        return defaultTopology(topology).getSRLGDisjointPaths(src, dst, riskProfile);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                  LinkWeight weight, Map<Link, Object> riskProfile) {
+        return defaultTopology(topology).getSRLGDisjointPaths(src, dst, weight, riskProfile);
+    }
+
+    @Override
     public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
         return defaultTopology(topology).isInfrastructure(connectPoint);
     }
diff --git a/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java b/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java
index a238c7f..5f84ee9 100644
--- a/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java
+++ b/core/net/src/main/java/org/onosproject/net/topology/impl/PathManager.java
@@ -27,6 +27,8 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultEdgeLink;
 import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DisjointPath;
+import org.onosproject.net.DefaultDisjointPath;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.EdgeLink;
 import org.onosproject.net.ElementId;
@@ -46,6 +48,8 @@
 
 import java.util.List;
 import java.util.Set;
+import java.util.Map;
+
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -128,6 +132,84 @@
         return edgeToEdgePaths(srcEdge, dstEdge, paths);
     }
 
+    @Override
+    public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) {
+        return getDisjointPaths(src, dst, null);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) {
+        checkNotNull(src, ELEMENT_ID_NULL);
+        checkNotNull(dst, ELEMENT_ID_NULL);
+
+        // 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 ImmutableSet.of();
+        }
+
+        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 edgeToEdgePathsDisjoint(srcEdge, dstEdge);
+        }
+
+        // Otherwise get all paths between the source and destination edge
+        // devices.
+        Topology topology = topologyService.currentTopology();
+        Set<DisjointPath> paths = weight == null ?
+                topologyService.getDisjointPaths(topology, srcDevice, dstDevice) :
+                topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight);
+
+        return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst,
+                                                  Map<Link, Object> riskProfile) {
+        return getSRLGDisjointPaths(src, dst, null, riskProfile);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst, LinkWeight weight,
+                                                  Map<Link, Object> riskProfile) {
+        checkNotNull(src, ELEMENT_ID_NULL);
+        checkNotNull(dst, ELEMENT_ID_NULL);
+
+        // 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 ImmutableSet.of();
+        }
+
+        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 edgeToEdgePathsDisjoint(srcEdge, dstEdge);
+        }
+
+        // Otherwise get all paths between the source and destination edge
+        // devices.
+        Topology topology = topologyService.currentTopology();
+        Set<DisjointPath> paths = weight == null ?
+                topologyService.getSRLGDisjointPaths(topology, srcDevice, dstDevice, riskProfile) :
+                topologyService.getSRLGDisjointPaths(topology, srcDevice, dstDevice, weight, riskProfile);
+
+        return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths);
+    }
+
     // Finds the host edge link if the element ID is a host id of an existing
     // host. Otherwise, if the host does not exist, it returns null and if
     // the element ID is not a host ID, returns NOT_HOST edge link.
@@ -162,6 +244,19 @@
         return endToEndPaths;
     }
 
+    private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink) {
+        Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(1);
+        endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, null));
+        return endToEndPaths;
+    }
+    private Set<DisjointPath> edgeToEdgePathsDisjoint(EdgeLink srcLink, EdgeLink dstLink, Set<DisjointPath> paths) {
+        Set<DisjointPath> endToEndPaths = Sets.newHashSetWithExpectedSize(paths.size());
+        for (DisjointPath path : paths) {
+            endToEndPaths.add(edgeToEdgePathD(srcLink, dstLink, path));
+        }
+        return endToEndPaths;
+    }
+
     // Produces a direct edge-to-edge path.
     private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink, Path path) {
         List<Link> links = Lists.newArrayListWithCapacity(2);
@@ -179,6 +274,13 @@
         return new DefaultPath(PID, links, 2);
     }
 
+    // Produces a direct edge-to-edge path.
+    private DisjointPath edgeToEdgePathD(EdgeLink srcLink, EdgeLink dstLink, DisjointPath path) {
+        return new DefaultDisjointPath(PID, (DefaultPath) edgeToEdgePath(srcLink, dstLink, path.primary()),
+                                       (DefaultPath) edgeToEdgePath(srcLink, dstLink, path.backup()));
+    }
+
+
     // Special value for edge link to represent that this is really not an
     // edge link since the src or dst are really an infrastructure device.
     private static class NotHost extends DefaultEdgeLink implements EdgeLink {
diff --git a/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java b/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java
index 04c4f1c1..7302b3c 100644
--- a/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java
+++ b/core/net/src/main/java/org/onosproject/net/topology/impl/TopologyManager.java
@@ -21,6 +21,7 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.provider.AbstractListenerProviderRegistry;
 import org.onosproject.event.Event;
 import org.onosproject.net.ConnectPoint;
@@ -46,6 +47,7 @@
 
 import java.util.List;
 import java.util.Set;
+import java.util.Map;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.security.AppGuard.checkPermission;
@@ -162,6 +164,42 @@
     }
 
     @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) {
+        checkNotNull(topology, TOPOLOGY_NULL);
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        return store.getDisjointPaths(topology, src, dst);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
+        checkNotNull(topology, TOPOLOGY_NULL);
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        checkNotNull(weight, "Link weight cannot be null");
+        return store.getDisjointPaths(topology, src, dst, weight);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                  Map<Link, Object> riskProfile) {
+        checkNotNull(topology, TOPOLOGY_NULL);
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        return store.getSRLGDisjointPaths(topology, src, dst, riskProfile);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight,
+                                                  Map<Link, Object> riskProfile) {
+        checkNotNull(topology, TOPOLOGY_NULL);
+        checkNotNull(src, DEVICE_ID_NULL);
+        checkNotNull(dst, DEVICE_ID_NULL);
+        checkNotNull(weight, "Link weight cannot be null");
+        return store.getSRLGDisjointPaths(topology, src, dst, weight, riskProfile);
+    }
+
+    @Override
     public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
         checkPermission(TOPOLOGY_READ);
         checkNotNull(topology, TOPOLOGY_NULL);
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java
index eb7a393..bf911e2 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java
@@ -21,7 +21,9 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.ElementId;
+import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.flow.TrafficSelector;
@@ -36,6 +38,7 @@
 
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
@@ -91,6 +94,28 @@
         public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
             return null;
         }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst,
+                                                      Map<Link, Object> riskProfile) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst, LinkWeight weight,
+                                                      Map<Link, Object> riskProfile) {
+            return null;
+        }
     }
 
     /**
diff --git a/core/net/src/test/java/org/onosproject/net/topology/impl/PathManagerTest.java b/core/net/src/test/java/org/onosproject/net/topology/impl/PathManagerTest.java
index 2a2d0b5..fc46c48 100644
--- a/core/net/src/test/java/org/onosproject/net/topology/impl/PathManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/topology/impl/PathManagerTest.java
@@ -19,9 +19,11 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.ElementId;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.host.HostServiceAdapter;
@@ -149,6 +151,28 @@
         public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
             return paths;
         }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                      Map<Link, Object> riskProfile) {
+            return null;
+        }
+
+        @Override
+        public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight,
+                                                      Map<Link, Object> riskProfile) {
+            return null;
+        }
     }
 
     // Fake entity to give out hosts.
diff --git a/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java b/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java
index 487fad9..4eeed7c 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/topology/impl/DistributedTopologyStore.java
@@ -21,6 +21,7 @@
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.Collections;
+import java.util.Map;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -40,6 +41,7 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
+import org.onosproject.net.DisjointPath;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.net.topology.ClusterId;
 import org.onosproject.net.topology.DefaultGraphDescription;
@@ -74,7 +76,6 @@
         implements TopologyStore {
 
     private final Logger log = getLogger(getClass());
-
     private volatile DefaultTopology current =
             new DefaultTopology(ProviderId.NONE,
                                 new DefaultGraphDescription(0L, System.currentTimeMillis(),
@@ -167,6 +168,29 @@
     }
 
     @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst) {
+        return defaultTopology(topology).getDisjointPaths(src, dst);
+    }
+
+    @Override
+    public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                              LinkWeight weight) {
+        return defaultTopology(topology).getDisjointPaths(src, dst, weight);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                  Map<Link, Object> riskProfile) {
+        return defaultTopology(topology).getSRLGDisjointPaths(src, dst, riskProfile);
+    }
+
+    @Override
+    public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
+                                                  LinkWeight weight, Map<Link, Object> riskProfile) {
+        return defaultTopology(topology).getSRLGDisjointPaths(src, dst, weight, riskProfile);
+    }
+
+    @Override
     public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
         return defaultTopology(topology).isInfrastructure(connectPoint);
     }
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/PathsWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/PathsWebResource.java
index baa1b1e..eae8c91 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/PathsWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/PathsWebResource.java
@@ -82,4 +82,30 @@
         return ok(root).build();
     }
 
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{src}/{dst}/disjoint")
+
+    public Response getDisjointPath(@PathParam("src") String src,
+                            @PathParam("dst") String dst) {
+        PathService pathService = get(PathService.class);
+
+        ElementId srcElement = isHostId(src);
+        ElementId dstElement = isHostId(dst);
+
+        if (srcElement == null) {
+            // Doesn't look like a host, assume it is a device
+            srcElement = DeviceId.deviceId(src);
+        }
+
+        if (dstElement == null) {
+            // Doesn't look like a host, assume it is a device
+            dstElement = DeviceId.deviceId(dst);
+        }
+        Set<org.onosproject.net.DisjointPath> paths =
+                pathService.getDisjointPaths(srcElement, dstElement);
+        ObjectNode root =
+                    encodeArray(org.onosproject.net.DisjointPath.class, "paths", paths);
+        return ok(root).build();
+    }
 }