Thomas Vachuska
Committed by Gerrit Code Review

Cleaned up the SRLG and disjoint path code and naming.

Change-Id: I02b6fe5ee1e3f5eadc4e88800386a23349ee5e58
......@@ -82,7 +82,7 @@ public interface PathService {
* @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,
Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
Map<Link, Object> riskProfile);
/**
......@@ -95,7 +95,7 @@ public interface PathService {
* @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,
Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
LinkWeight weight, Map<Link, Object> riskProfile);
}
......
......@@ -147,7 +147,7 @@ public interface TopologyService
* @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,
Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
Map<Link, Object> riskProfile);
/**
......@@ -161,8 +161,9 @@ public interface TopologyService
* @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,
Set<DisjointPath> getDisjointPaths(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.
......
......@@ -149,7 +149,7 @@ public interface TopologyStore extends Store<TopologyEvent, TopologyStoreDelegat
* 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,
Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
LinkWeight weight, Map<Link, Object> riskProfile);
/**
......@@ -162,7 +162,7 @@ public interface TopologyStore extends Store<TopologyEvent, TopologyStoreDelegat
* 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,
Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
Map<Link, Object> riskProfile);
......
......@@ -17,12 +17,10 @@ package org.onosproject.net.intent;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
import org.onlab.util.Bandwidth;
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;
......@@ -38,6 +36,9 @@ import org.onosproject.net.flow.criteria.Criterion.Type;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flow.instructions.Instructions.MetadataInstruction;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceRequest;
import org.onosproject.net.resource.ResourceType;
import org.onosproject.net.resource.link.BandwidthResource;
import org.onosproject.net.resource.link.BandwidthResourceRequest;
import org.onosproject.net.resource.link.LambdaResource;
......@@ -49,13 +50,10 @@ import org.onosproject.net.resource.link.LinkResourceRequest;
import org.onosproject.net.resource.link.LinkResourceService;
import org.onosproject.net.resource.link.MplsLabel;
import org.onosproject.net.resource.link.MplsLabelResourceAllocation;
import org.onosproject.net.resource.ResourceAllocation;
import org.onosproject.net.resource.ResourceRequest;
import org.onosproject.net.resource.ResourceType;
import org.onosproject.net.topology.DefaultTopologyEdge;
import org.onosproject.net.topology.DefaultTopologyVertex;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.PathServiceAdapter;
import org.onosproject.net.topology.TopologyVertex;
import org.onosproject.store.Timestamp;
......@@ -65,14 +63,11 @@ import java.util.Collections;
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;
import static org.onosproject.net.NetTestTools.createPath;
import static org.onosproject.net.NetTestTools.did;
import static org.onosproject.net.NetTestTools.link;
import static org.onosproject.net.NetTestTools.*;
/**
* Common mocks used by the intent framework tests.
......@@ -136,7 +131,7 @@ public class IntentTestsMocks {
/**
* Mock path service for creating paths within the test.
*/
public static class MockPathService implements PathService {
public static class MockPathService extends PathServiceAdapter {
final String[] pathHops;
final String[] reversePathHops;
......@@ -187,28 +182,6 @@ public class IntentTestsMocks {
}
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 {
......
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
/**
* Test adapter for path service.
*/
public class PathServiceAdapter implements PathService {
@Override
public Set<Path> getPaths(ElementId src, ElementId dst) {
return null;
}
@Override
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> getDisjointPaths(ElementId src, ElementId dst,
Map<Link, Object> riskProfile) {
return null;
}
@Override
public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
LinkWeight weight,
Map<Link, Object> riskProfile) {
return null;
}
}
......@@ -90,24 +90,27 @@ public class TopologyServiceAdapter implements TopologyService {
@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) {
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,
public Set<DisjointPath> getDisjointPaths(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,
public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
DeviceId dst, LinkWeight weight,
Map<Link, Object> riskProfile) {
return null;
}
......
......@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSetMultimap.Builder;
import org.onlab.graph.DijkstraGraphSearch;
import org.onlab.graph.DisjointPathPair;
import org.onlab.graph.GraphPathSearch;
import org.onlab.graph.GraphPathSearch.Result;
import org.onlab.graph.SRLGGraphSearch;
......@@ -49,11 +50,11 @@ import org.onosproject.net.topology.TopologyEdge;
import org.onosproject.net.topology.TopologyGraph;
import org.onosproject.net.topology.TopologyVertex;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
......@@ -333,7 +334,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @return set of shortest disjoint path pairs
*/
public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) {
return getDisjointPaths(src, dst, null);
return getDisjointPaths(src, dst, (LinkWeight) null);
}
/**
......@@ -369,27 +370,15 @@ public class DefaultTopology extends AbstractModel implements Topology {
*
* @param src source device
* @param dst destination device
* @param riskProfile map representing risk groups for each edge
* @return set of shortest disjoint paths
*/
public Set<DisjointPath> getSRLGDisjointPathsD(DeviceId src, DeviceId dst, Map<TopologyEdge, Object> riskProfile) {
return getSRLGDisjointPathsD(src, dst, null, riskProfile);
}
/**
* 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
* @return set of shortest disjoint paths
*/
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);
private Set<DisjointPath> disjointPaths(DeviceId src, DeviceId dst, LinkWeight weight,
Map<TopologyEdge, Object> riskProfile) {
DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
Set<TopologyVertex> vertices = graph.getVertexes();
if (!vertices.contains(srcV) || !vertices.contains(dstV)) {
// src or dst not part of the current graph
......@@ -416,35 +405,27 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @param riskProfile map representing risk groups for each link
* @return set of shortest disjoint paths
*/
public Set<DisjointPath> getSRLGDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight,
public Set<DisjointPath> getDisjointPaths(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() {
final Link cur = l;
Link cur = l;
public Link link() {
return cur;
}
public TopologyVertex src() {
return new TopologyVertex() {
public DeviceId deviceId() {
return src;
}
};
return () -> src;
}
public TopologyVertex dst() {
return new TopologyVertex() {
public DeviceId deviceId() {
return dst;
}
};
return () -> dst;
}
}, riskProfile.get(l));
}
return getSRLGDisjointPathsD(src, dst, weight, riskProfile2);
return disjointPaths(src, dst, weight, riskProfile2);
}
/**
......@@ -456,22 +437,20 @@ public class DefaultTopology extends AbstractModel implements Topology {
* @param riskProfile map representing risk groups for each link
* @return set of shortest disjoint paths
*/
public Set<DisjointPath> getSRLGDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) {
return getSRLGDisjointPaths(src, dst, null, riskProfile);
public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) {
return getDisjointPaths(src, dst, null, riskProfile);
}
// Converts graph path to a network path with the same cost.
private Path networkPath(org.onlab.graph.Path<TopologyVertex, TopologyEdge> path) {
List<Link> links = new ArrayList<>();
for (TopologyEdge edge : path.edges()) {
links.add(edge.link());
}
List<Link> links = path.edges().stream().map(TopologyEdge::link).collect(Collectors.toList());
return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
}
private DisjointPath networkDisjointPath(org.onlab.graph.DisjointPathPair<TopologyVertex, TopologyEdge> path) {
private DisjointPath networkDisjointPath(DisjointPathPair<TopologyVertex, TopologyEdge> path) {
return new DefaultDisjointPath(CORE_PROVIDER_ID,
(DefaultPath) networkPath(path.path1), (DefaultPath) networkPath(path.path2));
(DefaultPath) networkPath(path.primary()),
(DefaultPath) networkPath(path.secondary()));
}
// Searches for SCC clusters in the network topology graph using Tarjan
......@@ -484,6 +463,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
private ImmutableMap<ClusterId, TopologyCluster> buildTopologyClusters() {
ImmutableMap.Builder<ClusterId, TopologyCluster> clusterBuilder = ImmutableMap.builder();
SCCResult<TopologyVertex, TopologyEdge> results = clusterResults.get();
// Extract both vertexes and edges from the results; the lists form
// pairs along the same index.
List<Set<TopologyVertex>> clusterVertexes = results.clusterVertexes();
......
......@@ -127,15 +127,15 @@ public class SimpleTopologyStore
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
Map<Link, Object> riskProfile) {
return defaultTopology(topology).getSRLGDisjointPaths(src, dst, riskProfile);
return defaultTopology(topology).getDisjointPaths(src, dst, riskProfile);
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
LinkWeight weight, Map<Link, Object> riskProfile) {
return defaultTopology(topology).getSRLGDisjointPaths(src, dst, weight, riskProfile);
return defaultTopology(topology).getDisjointPaths(src, dst, weight, riskProfile);
}
@Override
......
......@@ -134,7 +134,7 @@ public class PathManager implements PathService {
@Override
public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst) {
return getDisjointPaths(src, dst, null);
return getDisjointPaths(src, dst, (LinkWeight) null);
}
@Override
......@@ -171,13 +171,13 @@ public class PathManager implements PathService {
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst,
public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst,
Map<Link, Object> riskProfile) {
return getSRLGDisjointPaths(src, dst, null, riskProfile);
return getDisjointPaths(src, dst, null, riskProfile);
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(ElementId src, ElementId dst, LinkWeight weight,
public Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, LinkWeight weight,
Map<Link, Object> riskProfile) {
checkNotNull(src, ELEMENT_ID_NULL);
checkNotNull(dst, ELEMENT_ID_NULL);
......@@ -204,8 +204,8 @@ public class PathManager implements PathService {
// devices.
Topology topology = topologyService.currentTopology();
Set<DisjointPath> paths = weight == null ?
topologyService.getSRLGDisjointPaths(topology, srcDevice, dstDevice, riskProfile) :
topologyService.getSRLGDisjointPaths(topology, srcDevice, dstDevice, weight, riskProfile);
topologyService.getDisjointPaths(topology, srcDevice, dstDevice, riskProfile) :
topologyService.getDisjointPaths(topology, srcDevice, dstDevice, weight, riskProfile);
return edgeToEdgePathsDisjoint(srcEdge, dstEdge, paths);
}
......@@ -249,6 +249,7 @@ public class PathManager implements PathService {
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) {
......
......@@ -70,6 +70,7 @@ public class TopologyManager
private static final String CLUSTER_ID_NULL = "Cluster ID cannot be null";
private static final String CLUSTER_NULL = "Topology cluster cannot be null";
public static final String CONNECTION_POINT_NULL = "Connection point cannot be null";
public static final String LINK_WEIGHT_NULL = "Link weight cannot be null";
private final Logger log = getLogger(getClass());
......@@ -172,31 +173,33 @@ public class TopologyManager
}
@Override
public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
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");
checkNotNull(weight, LINK_WEIGHT_NULL);
return store.getDisjointPaths(topology, src, dst, weight);
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
public Set<DisjointPath> getDisjointPaths(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);
return store.getDisjointPaths(topology, src, dst, riskProfile);
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight,
public Set<DisjointPath> getDisjointPaths(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);
checkNotNull(weight, LINK_WEIGHT_NULL);
return store.getDisjointPaths(topology, src, dst, weight, riskProfile);
}
@Override
......
......@@ -21,9 +21,7 @@ import org.onosproject.TestApplicationId;
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;
......@@ -33,12 +31,10 @@ import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentTestsMocks;
import org.onosproject.net.intent.LinkCollectionIntent;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.PathServiceAdapter;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.hamcrest.CoreMatchers.instanceOf;
......@@ -63,7 +59,7 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
/**
* Mock path service for creating paths within the test.
*/
private static class MockPathService implements PathService {
private static class MockPathService extends PathServiceAdapter {
final String[] pathHops;
......@@ -89,33 +85,6 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes
return result;
}
@Override
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;
}
}
/**
......
......@@ -19,19 +19,15 @@ import org.junit.After;
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;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.PathService;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.net.topology.TopologyServiceAdapter;
import java.util.HashMap;
......@@ -139,7 +135,7 @@ public class PathManagerTest {
}
// Fake entity to give out paths.
private class FakeTopoMgr extends TopologyServiceAdapter implements TopologyService {
private class FakeTopoMgr extends TopologyServiceAdapter {
Set<Path> paths = new HashSet<>();
@Override
......@@ -151,32 +147,10 @@ public class PathManagerTest {
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.
private class FakeHostMgr extends HostServiceAdapter implements HostService {
private class FakeHostMgr extends HostServiceAdapter {
private Map<HostId, Host> hosts = new HashMap<>();
@Override
......
......@@ -179,15 +179,15 @@ public class DistributedTopologyStore
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
Map<Link, Object> riskProfile) {
return defaultTopology(topology).getSRLGDisjointPaths(src, dst, riskProfile);
return defaultTopology(topology).getDisjointPaths(src, dst, riskProfile);
}
@Override
public Set<DisjointPath> getSRLGDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src, DeviceId dst,
LinkWeight weight, Map<Link, Object> riskProfile) {
return defaultTopology(topology).getSRLGDisjointPaths(src, dst, weight, riskProfile);
return defaultTopology(topology).getDisjointPaths(src, dst, weight, riskProfile);
}
@Override
......
......@@ -19,52 +19,67 @@ package org.onlab.graph;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import static com.google.common.collect.ImmutableSet.of;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Pair of disjoint paths.
*
* @param <V> type of vertex
* @param <E> type of edge
*/
public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Path<V, E> {
public Path<V, E> path1, path2;
boolean usingPath1 = true;
private Path<V, E> primary, secondary;
boolean primaryActive = true;
/**
* Creates a Disjoint Path Pair from two paths.
* Creates a disjoint path pair from two paths.
*
* @param p1 first path
* @param p2 second path
* @param primary primary path
* @param secondary secondary path
*/
public DisjointPathPair(Path<V, E> p1, Path<V, E> p2) {
path1 = p1;
path2 = p2;
public DisjointPathPair(Path<V, E> primary, Path<V, E> secondary) {
this.primary = primary;
this.secondary = secondary;
}
@Override
public V src() {
return path1.src();
return primary.src();
}
@Override
public V dst() {
return path1.dst();
return primary.dst();
}
/**
* Returns the primary path.
*
* @return primary path
*/
public Path<V, E> primary() {
return primary;
}
/**
* Returns the secondary path.
*
* @return primary path
*/
public Path<V, E> secondary() {
return secondary;
}
@Override
public double cost() {
if (!hasBackup()) {
return path1.cost();
}
return path1.cost() + path2.cost();
return hasBackup() ? primary.cost() + secondary.cost() : primary.cost();
}
@Override
public List<E> edges() {
if (usingPath1 || !hasBackup()) {
return path1.edges();
} else {
return path2.edges();
}
return primaryActive || !hasBackup() ? primary.edges() : secondary.edges();
}
/**
......@@ -73,7 +88,7 @@ public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Pa
* @return boolean representing whether it has backup
*/
public boolean hasBackup() {
return path2 != null && path2.edges() != null;
return secondary != null && secondary.edges() != null;
}
@Override
......@@ -88,13 +103,8 @@ public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Pa
@Override
public int hashCode() {
Set<Path<V, E>> paths;
if (!hasBackup()) {
paths = of(path1);
} else {
paths = of(path1, path2);
}
return Objects.hash(paths);
return hasBackup() ? Objects.hash(primary) + Objects.hash(secondary) :
Objects.hash(primary);
}
@Override
......@@ -106,10 +116,10 @@ public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Pa
final DisjointPathPair other = (DisjointPathPair) obj;
return Objects.equals(this.src(), other.src()) &&
Objects.equals(this.dst(), other.dst()) &&
(Objects.equals(this.path1, other.path1) &&
Objects.equals(this.path2, other.path2)) ||
(Objects.equals(this.path1, other.path2) &&
Objects.equals(this.path2, other.path1));
(Objects.equals(this.primary, other.primary) &&
Objects.equals(this.secondary, other.secondary)) ||
(Objects.equals(this.primary, other.secondary) &&
Objects.equals(this.secondary, other.primary));
}
return false;
}
......@@ -120,9 +130,6 @@ public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Pa
* @return number of paths
*/
public int size() {
if (hasBackup()) {
return 2;
}
return 1;
return hasBackup() ? 2 : 1;
}
}
......
......@@ -17,44 +17,37 @@
package org.onlab.graph;
import org.junit.Test;
import java.util.Set;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import static com.google.common.collect.ImmutableSet.of;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
/**
* Test of the Suurballe backup path algorithm.
*/
public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
@Override
protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
return new SRLGGraphSearch<TestVertex, TestEdge>(null);
return new SRLGGraphSearch<>(null);
}
public void setWeights() {
weight = new EdgeWeight<TestVertex, TestEdge>() {
@Override
public double weight(TestEdge edge) {
return edge.weight();
}
};
}
public void setDefaultWeights() {
weight = null;
}
@Override
public void defaultGraphTest() {
}
@Override
public void defaultHopCountWeight() {
}
@Test
......@@ -66,34 +59,34 @@ public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
TestEdge dC = new TestEdge(D, C, 1);
Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
of(aB, bC, aD, dC));
Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
Map<TestEdge, Integer> riskProfile = new HashMap<>();
riskProfile.put(aB, 0);
riskProfile.put(bC, 0);
riskProfile.put(aD, 1);
riskProfile.put(dC, 1);
SRLGGraphSearch<TestVertex, TestEdge> search =
new SRLGGraphSearch<TestVertex, TestEdge>(2, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, GraphPathSearch.ALL_PATHS).paths();
SRLGGraphSearch<TestVertex, TestEdge> search = new SRLGGraphSearch<>(2, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, ALL_PATHS).paths();
System.out.println("\n\n\n" + paths + "\n\n\n");
assertTrue("one disjoint path pair found", paths.size() == 1);
assertEquals("one disjoint path pair found", 1, paths.size());
checkIsDisjoint(paths.iterator().next(), riskProfile);
}
public void checkIsDisjoint(Path<TestVertex, TestEdge> p, Map<TestEdge, Integer> risks) {
assertTrue("The path is not a DisjointPathPair", (p instanceof DisjointPathPair));
DisjointPathPair<TestVertex, TestEdge> q = (DisjointPathPair) p;
Set<Integer> p1Risks = new HashSet<Integer>();
Set<Integer> p2Risks = new HashSet<Integer>();
for (TestEdge e: q.edges()) {
Set<Integer> p1Risks = new HashSet<>();
for (TestEdge e : q.edges()) {
p1Risks.add(risks.get(e));
}
if (!q.hasBackup()) {
return;
}
Path<TestVertex, TestEdge> pq = q.path2;
Path<TestVertex, TestEdge> pq = q.secondary();
for (TestEdge e: pq.edges()) {
assertTrue("The paths are not disjoint", !p1Risks.contains(risks.get(e)));
}
}
@Test
public void complexGraphTest() {
setDefaultWeights();
......@@ -105,16 +98,15 @@ public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
TestEdge bE = new TestEdge(B, E, 1);
Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
of(aB, bC, aD, dC, cE, bE));
Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
Map<TestEdge, Integer> riskProfile = new HashMap<>();
riskProfile.put(aB, 0);
riskProfile.put(bC, 0);
riskProfile.put(aD, 1);
riskProfile.put(dC, 1);
riskProfile.put(cE, 2);
riskProfile.put(bE, 3);
SRLGGraphSearch<TestVertex, TestEdge> search =
new SRLGGraphSearch<TestVertex, TestEdge>(4, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, GraphPathSearch.ALL_PATHS).paths();
SRLGGraphSearch<TestVertex, TestEdge> search = new SRLGGraphSearch<>(4, riskProfile);
search.search(graph, A, E, weight, ALL_PATHS).paths();
}
@Test
......@@ -128,19 +120,19 @@ public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
TestEdge cE = new TestEdge(C, E, 1);
Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
of(aB, bE, aD, dE, aC, cE));
Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
Map<TestEdge, Integer> riskProfile = new HashMap<>();
riskProfile.put(aB, 0);
riskProfile.put(bE, 1);
riskProfile.put(aD, 2);
riskProfile.put(dE, 3);
riskProfile.put(aC, 4);
riskProfile.put(cE, 5);
SRLGGraphSearch<TestVertex, TestEdge> search =
new SRLGGraphSearch<TestVertex, TestEdge>(6, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, GraphPathSearch.ALL_PATHS).paths();
SRLGGraphSearch<TestVertex, TestEdge> search = new SRLGGraphSearch<>(6, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, ALL_PATHS).paths();
assertTrue("> one disjoint path pair found", paths.size() >= 1);
checkIsDisjoint(paths.iterator().next(), riskProfile);
}
@Test
public void onePath() {
setDefaultWeights();
......@@ -150,17 +142,17 @@ public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
TestEdge dC = new TestEdge(D, C, 1);
Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
of(aB, bC, aD, dC));
Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
Map<TestEdge, Integer> riskProfile = new HashMap<>();
riskProfile.put(aB, 0);
riskProfile.put(bC, 0);
riskProfile.put(aD, 1);
riskProfile.put(dC, 0);
SRLGGraphSearch<TestVertex, TestEdge> search =
new SRLGGraphSearch<TestVertex, TestEdge>(2, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, GraphPathSearch.ALL_PATHS).paths();
SRLGGraphSearch<TestVertex, TestEdge> search = new SRLGGraphSearch<>(2, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, ALL_PATHS).paths();
System.out.println(paths);
assertTrue("no disjoint path pairs found", paths.size() == 0);
}
@Test
public void noPath() {
setDefaultWeights();
......@@ -175,9 +167,8 @@ public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
riskProfile.put(bC, 0);
riskProfile.put(aD, 1);
riskProfile.put(dC, 0);
SRLGGraphSearch<TestVertex, TestEdge> search =
new SRLGGraphSearch<>(2, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, GraphPathSearch.ALL_PATHS).paths();
SRLGGraphSearch<TestVertex, TestEdge> search = new SRLGGraphSearch<>(2, riskProfile);
Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, ALL_PATHS).paths();
assertTrue("no disjoint path pairs found", paths.size() == 0);
}
}
......
......@@ -15,7 +15,11 @@
*/
package org.onosproject.rest.resources;
import java.util.Set;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.HostId;
import org.onosproject.net.topology.PathService;
import org.onosproject.rest.AbstractWebResource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
......@@ -23,14 +27,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onosproject.net.DeviceId;
import org.onosproject.net.ElementId;
import org.onosproject.net.HostId;
import org.onosproject.net.topology.PathService;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.rest.AbstractWebResource;
import java.util.Set;
/**
* Compute paths in the network graph.
......@@ -50,6 +47,17 @@ public class PathsWebResource extends AbstractWebResource {
}
/**
* Returns either host id or device id, depending on the ID format.
*
* @param id host or device id string
* @return element id
*/
private ElementId elementId(String id) {
ElementId elementId = isHostId(id);
return elementId != null ? elementId : DeviceId.deviceId(id);
}
/**
* Get all shortest paths between any two hosts or devices.
* Returns array of all shortest paths between any two elements.
*
......@@ -63,49 +71,27 @@ public class PathsWebResource extends AbstractWebResource {
public Response getPath(@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.Path> paths = pathService.getPaths(srcElement, dstElement);
ObjectNode root = encodeArray(org.onosproject.net.Path.class, "paths", paths);
return ok(root).build();
Set<org.onosproject.net.Path> paths =
pathService.getPaths(elementId(src), elementId(dst));
return ok(encodeArray(org.onosproject.net.Path.class, "paths", paths)).build();
}
/**
* Get all shortest disjoint paths between any two hosts or devices.
* Returns array of all shortest disjoint paths between any two elements.
*
* @param src source identifier
* @param dst destination identifier
* @return path data
*/
@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();
pathService.getDisjointPaths(elementId(src), elementId(dst));
return ok(encodeArray(org.onosproject.net.DisjointPath.class, "paths", paths)).build();
}
}
......