mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-21 20:31:00 +02:00
Refactoring to eliminate duplicate DefaultTopology and DefaultTopologyGraph; eliminating a few fixmes.
Change-Id: I4461b6f1c8ae60d39f5da909bf6995294cbfa84d
This commit is contained in:
parent
a776fe2619
commit
930a8ee16a
@ -15,10 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.onosproject.net.topology;
|
package org.onosproject.net.topology;
|
||||||
|
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.onosproject.net.AbstractDescription;
|
import org.onosproject.net.AbstractDescription;
|
||||||
import org.onosproject.net.ConnectPoint;
|
import org.onosproject.net.ConnectPoint;
|
||||||
import org.onosproject.net.Device;
|
import org.onosproject.net.Device;
|
||||||
@ -27,14 +25,15 @@ import org.onosproject.net.Link;
|
|||||||
import org.onosproject.net.SparseAnnotations;
|
import org.onosproject.net.SparseAnnotations;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import java.util.Map;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of an immutable topology graph data carrier.
|
* Default implementation of an immutable topology graph data carrier.
|
||||||
*/
|
*/
|
||||||
public class DefaultGraphDescription extends AbstractDescription
|
public class DefaultGraphDescription extends AbstractDescription
|
||||||
implements GraphDescription {
|
implements GraphDescription {
|
||||||
|
|
||||||
private static final Logger log = getLogger(DefaultGraphDescription.class);
|
private static final Logger log = getLogger(DefaultGraphDescription.class);
|
||||||
|
|
||||||
@ -43,26 +42,22 @@ implements GraphDescription {
|
|||||||
private final ImmutableSet<TopologyVertex> vertexes;
|
private final ImmutableSet<TopologyVertex> vertexes;
|
||||||
private final ImmutableSet<TopologyEdge> edges;
|
private final ImmutableSet<TopologyEdge> edges;
|
||||||
|
|
||||||
private final Map<DeviceId, TopologyVertex> vertexesById = Maps
|
private final Map<DeviceId, TopologyVertex> vertexesById = Maps.newHashMap();
|
||||||
.newHashMap();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a minimal topology graph description to allow core to construct
|
* Creates a minimal topology graph description to allow core to construct
|
||||||
* and process the topology graph.
|
* and process the topology graph.
|
||||||
*
|
*
|
||||||
* @param nanos time in nanos of when the topology description was created
|
* @param nanos time in nanos of when the topology description was created
|
||||||
*
|
* @param devices collection of infrastructure devices
|
||||||
* @param devices collection of infrastructure devices
|
* @param links collection of infrastructure links
|
||||||
*
|
|
||||||
* @param links collection of infrastructure links
|
|
||||||
*
|
|
||||||
* @param annotations optional key/value annotations map
|
* @param annotations optional key/value annotations map
|
||||||
* @deprecated in Cardinal Release
|
* @deprecated in Cardinal Release
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public DefaultGraphDescription(long nanos, Iterable<Device> devices,
|
public DefaultGraphDescription(long nanos, Iterable<Device> devices,
|
||||||
Iterable<Link> links,
|
Iterable<Link> links,
|
||||||
SparseAnnotations... annotations) {
|
SparseAnnotations... annotations) {
|
||||||
this(nanos, System.currentTimeMillis(), devices, links, annotations);
|
this(nanos, System.currentTimeMillis(), devices, links, annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,21 +65,16 @@ implements GraphDescription {
|
|||||||
* Creates a minimal topology graph description to allow core to construct
|
* Creates a minimal topology graph description to allow core to construct
|
||||||
* and process the topology graph.
|
* and process the topology graph.
|
||||||
*
|
*
|
||||||
* @param nanos time in nanos of when the topology description was created
|
* @param nanos time in nanos of when the topology description was created
|
||||||
*
|
* @param millis time in millis of when the topology description was created
|
||||||
* @param millis time in millis of when the topology description was created
|
* @param devices collection of infrastructure devices
|
||||||
*
|
* @param links collection of infrastructure links
|
||||||
* @param devices collection of infrastructure devices
|
|
||||||
*
|
|
||||||
* @param links collection of infrastructure links
|
|
||||||
*
|
|
||||||
* @param annotations optional key/value annotations map
|
* @param annotations optional key/value annotations map
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public DefaultGraphDescription(long nanos, long millis,
|
public DefaultGraphDescription(long nanos, long millis,
|
||||||
Iterable<Device> devices,
|
Iterable<Device> devices,
|
||||||
Iterable<Link> links,
|
Iterable<Link> links,
|
||||||
SparseAnnotations... annotations) {
|
SparseAnnotations... annotations) {
|
||||||
super(annotations);
|
super(annotations);
|
||||||
this.nanos = nanos;
|
this.nanos = nanos;
|
||||||
this.creationTime = millis;
|
this.creationTime = millis;
|
||||||
@ -114,8 +104,7 @@ implements GraphDescription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Builds a set of topology vertexes from the specified list of devices
|
// Builds a set of topology vertexes from the specified list of devices
|
||||||
private ImmutableSet<TopologyVertex>
|
private ImmutableSet<TopologyVertex> buildVertexes(Iterable<Device> devices) {
|
||||||
buildVertexes(Iterable<Device> devices) {
|
|
||||||
ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder();
|
ImmutableSet.Builder<TopologyVertex> vertexes = ImmutableSet.builder();
|
||||||
for (Device device : devices) {
|
for (Device device : devices) {
|
||||||
TopologyVertex vertex = new DefaultTopologyVertex(device.id());
|
TopologyVertex vertex = new DefaultTopologyVertex(device.id());
|
||||||
|
@ -13,20 +13,14 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.onosproject.store.topology.impl;
|
package org.onosproject.common;
|
||||||
|
|
||||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
|
||||||
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
|
|
||||||
import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
|
|
||||||
import static org.onosproject.net.Link.State.ACTIVE;
|
|
||||||
import static org.onosproject.net.Link.State.INACTIVE;
|
|
||||||
import static org.onosproject.net.Link.Type.INDIRECT;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
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.DijkstraGraphSearch;
|
||||||
import org.onlab.graph.GraphPathSearch;
|
import org.onlab.graph.GraphPathSearch;
|
||||||
import org.onlab.graph.GraphPathSearch.Result;
|
import org.onlab.graph.GraphPathSearch.Result;
|
||||||
@ -50,14 +44,18 @@ import org.onosproject.net.topology.TopologyEdge;
|
|||||||
import org.onosproject.net.topology.TopologyGraph;
|
import org.onosproject.net.topology.TopologyGraph;
|
||||||
import org.onosproject.net.topology.TopologyVertex;
|
import org.onosproject.net.topology.TopologyVertex;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import java.util.ArrayList;
|
||||||
import com.google.common.base.Suppliers;
|
import java.util.List;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import java.util.Map;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import java.util.Set;
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
|
||||||
import com.google.common.collect.ImmutableSetMultimap.Builder;
|
import static com.google.common.base.MoreObjects.toStringHelper;
|
||||||
|
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
|
||||||
|
import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
|
||||||
|
import static org.onosproject.net.Link.State.ACTIVE;
|
||||||
|
import static org.onosproject.net.Link.State.INACTIVE;
|
||||||
|
import static org.onosproject.net.Link.Type.INDIRECT;
|
||||||
|
|
||||||
// FIXME: Move to onos-core-common when ready
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the topology descriptor. This carries the backing
|
* Default implementation of the topology descriptor. This carries the backing
|
||||||
* topology data.
|
* topology data.
|
||||||
@ -83,19 +81,17 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
/**
|
/**
|
||||||
* Creates a topology descriptor attributed to the specified provider.
|
* Creates a topology descriptor attributed to the specified provider.
|
||||||
*
|
*
|
||||||
* @param providerId
|
* @param providerId identity of the provider
|
||||||
* identity of the provider
|
* @param description data describing the new topology
|
||||||
* @param description
|
|
||||||
* data describing the new topology
|
|
||||||
*/
|
*/
|
||||||
DefaultTopology(ProviderId providerId, GraphDescription description) {
|
public DefaultTopology(ProviderId providerId, GraphDescription description) {
|
||||||
super(providerId);
|
super(providerId);
|
||||||
this.time = description.timestamp();
|
this.time = description.timestamp();
|
||||||
this.creationTime = description.creationTime();
|
this.creationTime = description.creationTime();
|
||||||
|
|
||||||
// Build the graph
|
// Build the graph
|
||||||
this.graph = new DefaultTopologyGraph(description.vertexes(),
|
this.graph = new DefaultTopologyGraph(description.vertexes(),
|
||||||
description.edges());
|
description.edges());
|
||||||
|
|
||||||
this.clusterResults = Suppliers.memoize(() -> searchForClusters());
|
this.clusterResults = Suppliers.memoize(() -> searchForClusters());
|
||||||
this.clusters = Suppliers.memoize(() -> buildTopologyClusters());
|
this.clusters = Suppliers.memoize(() -> buildTopologyClusters());
|
||||||
@ -104,8 +100,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
|
|
||||||
this.weight = new HopCountLinkWeight(graph.getVertexes().size());
|
this.weight = new HopCountLinkWeight(graph.getVertexes().size());
|
||||||
this.broadcastSets = Suppliers.memoize(() -> buildBroadcastSets());
|
this.broadcastSets = Suppliers.memoize(() -> buildBroadcastSets());
|
||||||
this.infrastructurePoints = Suppliers
|
this.infrastructurePoints = Suppliers.memoize(() -> findInfrastructurePoints());
|
||||||
.memoize(() -> findInfrastructurePoints());
|
|
||||||
this.computeCost = Math.max(0, System.nanoTime() - time);
|
this.computeCost = Math.max(0, System.nanoTime() - time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +151,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
*
|
*
|
||||||
* @return topology graph
|
* @return topology graph
|
||||||
*/
|
*/
|
||||||
TopologyGraph getGraph() {
|
public TopologyGraph getGraph() {
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +160,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
*
|
*
|
||||||
* @return set of clusters
|
* @return set of clusters
|
||||||
*/
|
*/
|
||||||
Set<TopologyCluster> getClusters() {
|
public Set<TopologyCluster> getClusters() {
|
||||||
return ImmutableSet.copyOf(clusters.get().values());
|
return ImmutableSet.copyOf(clusters.get().values());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,10 +168,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Returns the specified topology cluster.
|
* Returns the specified topology cluster.
|
||||||
*
|
*
|
||||||
* @param clusterId cluster identifier
|
* @param clusterId cluster identifier
|
||||||
*
|
|
||||||
* @return topology cluster
|
* @return topology cluster
|
||||||
*/
|
*/
|
||||||
TopologyCluster getCluster(ClusterId clusterId) {
|
public TopologyCluster getCluster(ClusterId clusterId) {
|
||||||
return clusters.get().get(clusterId);
|
return clusters.get().get(clusterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,10 +178,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Returns the topology cluster that contains the given device.
|
* Returns the topology cluster that contains the given device.
|
||||||
*
|
*
|
||||||
* @param deviceId device identifier
|
* @param deviceId device identifier
|
||||||
*
|
|
||||||
* @return topology cluster
|
* @return topology cluster
|
||||||
*/
|
*/
|
||||||
TopologyCluster getCluster(DeviceId deviceId) {
|
public TopologyCluster getCluster(DeviceId deviceId) {
|
||||||
return clustersByDevice().get(deviceId);
|
return clustersByDevice().get(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,10 +188,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Returns the set of cluster devices.
|
* Returns the set of cluster devices.
|
||||||
*
|
*
|
||||||
* @param cluster topology cluster
|
* @param cluster topology cluster
|
||||||
*
|
|
||||||
* @return cluster devices
|
* @return cluster devices
|
||||||
*/
|
*/
|
||||||
Set<DeviceId> getClusterDevices(TopologyCluster cluster) {
|
public Set<DeviceId> getClusterDevices(TopologyCluster cluster) {
|
||||||
return devicesByCluster().get(cluster);
|
return devicesByCluster().get(cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,10 +198,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Returns the set of cluster links.
|
* Returns the set of cluster links.
|
||||||
*
|
*
|
||||||
* @param cluster topology cluster
|
* @param cluster topology cluster
|
||||||
*
|
|
||||||
* @return cluster links
|
* @return cluster links
|
||||||
*/
|
*/
|
||||||
Set<Link> getClusterLinks(TopologyCluster cluster) {
|
public Set<Link> getClusterLinks(TopologyCluster cluster) {
|
||||||
return linksByCluster().get(cluster);
|
return linksByCluster().get(cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,10 +208,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Indicates whether the given point is an infrastructure link end-point.
|
* Indicates whether the given point is an infrastructure link end-point.
|
||||||
*
|
*
|
||||||
* @param connectPoint connection point
|
* @param connectPoint connection point
|
||||||
*
|
|
||||||
* @return true if infrastructure
|
* @return true if infrastructure
|
||||||
*/
|
*/
|
||||||
boolean isInfrastructure(ConnectPoint connectPoint) {
|
public boolean isInfrastructure(ConnectPoint connectPoint) {
|
||||||
return infrastructurePoints.get().contains(connectPoint);
|
return infrastructurePoints.get().contains(connectPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,10 +218,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Indicates whether the given point is part of a broadcast set.
|
* Indicates whether the given point is part of a broadcast set.
|
||||||
*
|
*
|
||||||
* @param connectPoint connection point
|
* @param connectPoint connection point
|
||||||
*
|
|
||||||
* @return true if in broadcast set
|
* @return true if in broadcast set
|
||||||
*/
|
*/
|
||||||
boolean isBroadcastPoint(ConnectPoint connectPoint) {
|
public boolean isBroadcastPoint(ConnectPoint connectPoint) {
|
||||||
// Any non-infrastructure, i.e. edge points are assumed to be OK.
|
// Any non-infrastructure, i.e. edge points are assumed to be OK.
|
||||||
if (!isInfrastructure(connectPoint)) {
|
if (!isInfrastructure(connectPoint)) {
|
||||||
return true;
|
return true;
|
||||||
@ -241,7 +230,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
TopologyCluster cluster = clustersByDevice().get(connectPoint.deviceId());
|
TopologyCluster cluster = clustersByDevice().get(connectPoint.deviceId());
|
||||||
if (cluster == null) {
|
if (cluster == null) {
|
||||||
throw new IllegalArgumentException("No cluster found for device "
|
throw new IllegalArgumentException("No cluster found for device "
|
||||||
+ connectPoint.deviceId());
|
+ connectPoint.deviceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the broadcast set is null or empty, or if the point explicitly
|
// If the broadcast set is null or empty, or if the point explicitly
|
||||||
@ -254,10 +243,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Returns the size of the cluster broadcast set.
|
* Returns the size of the cluster broadcast set.
|
||||||
*
|
*
|
||||||
* @param clusterId cluster identifier
|
* @param clusterId cluster identifier
|
||||||
*
|
|
||||||
* @return size of the cluster broadcast set
|
* @return size of the cluster broadcast set
|
||||||
*/
|
*/
|
||||||
int broadcastSetSize(ClusterId clusterId) {
|
public int broadcastSetSize(ClusterId clusterId) {
|
||||||
return broadcastSets.get().get(clusterId).size();
|
return broadcastSets.get().get(clusterId).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,12 +254,10 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* destination devices.
|
* destination devices.
|
||||||
*
|
*
|
||||||
* @param src source device
|
* @param src source device
|
||||||
*
|
|
||||||
* @param dst destination device
|
* @param dst destination device
|
||||||
*
|
|
||||||
* @return set of shortest paths
|
* @return set of shortest paths
|
||||||
*/
|
*/
|
||||||
Set<Path> getPaths(DeviceId src, DeviceId dst) {
|
public Set<Path> getPaths(DeviceId src, DeviceId dst) {
|
||||||
return getPaths(src, dst, null);
|
return getPaths(src, dst, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,15 +265,12 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
* Computes on-demand the set of shortest paths between source and
|
* Computes on-demand the set of shortest paths between source and
|
||||||
* destination devices.
|
* destination devices.
|
||||||
*
|
*
|
||||||
* @param src source device
|
* @param src source device
|
||||||
*
|
* @param dst destination device
|
||||||
* @param dst destination device
|
|
||||||
*
|
|
||||||
* @param weight link weight function
|
* @param weight link weight function
|
||||||
*
|
|
||||||
* @return set of shortest paths
|
* @return set of shortest paths
|
||||||
*/
|
*/
|
||||||
Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
|
public Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
|
||||||
final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
|
final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
|
||||||
final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
|
final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst);
|
||||||
Set<TopologyVertex> vertices = graph.getVertexes();
|
Set<TopologyVertex> vertices = graph.getVertexes();
|
||||||
@ -470,10 +453,9 @@ public class DefaultTopology extends AbstractModel implements Topology {
|
|||||||
final ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster;
|
final ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster;
|
||||||
final ImmutableSetMultimap<TopologyCluster, Link> linksByCluster;
|
final ImmutableSetMultimap<TopologyCluster, Link> linksByCluster;
|
||||||
|
|
||||||
public ClusterIndexes(
|
public ClusterIndexes(ImmutableMap<DeviceId, TopologyCluster> clustersByDevice,
|
||||||
ImmutableMap<DeviceId, TopologyCluster> clustersByDevice,
|
ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster,
|
||||||
ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster,
|
ImmutableSetMultimap<TopologyCluster, Link> linksByCluster) {
|
||||||
ImmutableSetMultimap<TopologyCluster, Link> linksByCluster) {
|
|
||||||
this.clustersByDevice = clustersByDevice;
|
this.clustersByDevice = clustersByDevice;
|
||||||
this.devicesByCluster = devicesByCluster;
|
this.devicesByCluster = devicesByCluster;
|
||||||
this.linksByCluster = linksByCluster;
|
this.linksByCluster = linksByCluster;
|
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.onosproject.store.trivial;
|
package org.onosproject.common;
|
||||||
|
|
||||||
import org.onlab.graph.AdjacencyListsGraph;
|
import org.onlab.graph.AdjacencyListsGraph;
|
||||||
import org.onosproject.net.topology.TopologyEdge;
|
import org.onosproject.net.topology.TopologyEdge;
|
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.onosproject.store.trivial;
|
package org.onosproject.common;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
@ -1,492 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014-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.store.trivial;
|
|
||||||
|
|
||||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
|
||||||
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
|
|
||||||
import static org.onosproject.core.CoreService.CORE_PROVIDER_ID;
|
|
||||||
import static org.onosproject.net.Link.State.ACTIVE;
|
|
||||||
import static org.onosproject.net.Link.State.INACTIVE;
|
|
||||||
import static org.onosproject.net.Link.Type.INDIRECT;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.onlab.graph.DijkstraGraphSearch;
|
|
||||||
import org.onlab.graph.GraphPathSearch;
|
|
||||||
import org.onlab.graph.GraphPathSearch.Result;
|
|
||||||
import org.onlab.graph.TarjanGraphSearch;
|
|
||||||
import org.onlab.graph.TarjanGraphSearch.SCCResult;
|
|
||||||
import org.onosproject.net.AbstractModel;
|
|
||||||
import org.onosproject.net.ConnectPoint;
|
|
||||||
import org.onosproject.net.DefaultPath;
|
|
||||||
import org.onosproject.net.DeviceId;
|
|
||||||
import org.onosproject.net.Link;
|
|
||||||
import org.onosproject.net.Path;
|
|
||||||
import org.onosproject.net.provider.ProviderId;
|
|
||||||
import org.onosproject.net.topology.ClusterId;
|
|
||||||
import org.onosproject.net.topology.DefaultTopologyCluster;
|
|
||||||
import org.onosproject.net.topology.DefaultTopologyVertex;
|
|
||||||
import org.onosproject.net.topology.GraphDescription;
|
|
||||||
import org.onosproject.net.topology.LinkWeight;
|
|
||||||
import org.onosproject.net.topology.Topology;
|
|
||||||
import org.onosproject.net.topology.TopologyCluster;
|
|
||||||
import org.onosproject.net.topology.TopologyEdge;
|
|
||||||
import org.onosproject.net.topology.TopologyGraph;
|
|
||||||
import org.onosproject.net.topology.TopologyVertex;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.common.base.Suppliers;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
|
||||||
import com.google.common.collect.ImmutableSetMultimap.Builder;
|
|
||||||
|
|
||||||
// FIXME: Move to onos-core-common when ready
|
|
||||||
/**
|
|
||||||
* Default implementation of the topology descriptor. This carries the backing
|
|
||||||
* topology data.
|
|
||||||
*/
|
|
||||||
public class DefaultTopology extends AbstractModel implements Topology {
|
|
||||||
|
|
||||||
private static final DijkstraGraphSearch<TopologyVertex, TopologyEdge> DIJKSTRA = new DijkstraGraphSearch<>();
|
|
||||||
private static final TarjanGraphSearch<TopologyVertex, TopologyEdge> TARJAN = new TarjanGraphSearch<>();
|
|
||||||
|
|
||||||
private final long time;
|
|
||||||
private final long creationTime;
|
|
||||||
private final long computeCost;
|
|
||||||
private final TopologyGraph graph;
|
|
||||||
|
|
||||||
private final LinkWeight weight;
|
|
||||||
private final Supplier<SCCResult<TopologyVertex, TopologyEdge>> clusterResults;
|
|
||||||
private final Supplier<ImmutableMap<ClusterId, TopologyCluster>> clusters;
|
|
||||||
private final Supplier<ImmutableSet<ConnectPoint>> infrastructurePoints;
|
|
||||||
private final Supplier<ImmutableSetMultimap<ClusterId, ConnectPoint>> broadcastSets;
|
|
||||||
|
|
||||||
private final Supplier<ClusterIndexes> clusterIndexes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a topology descriptor attributed to the specified provider.
|
|
||||||
*
|
|
||||||
* @param providerId
|
|
||||||
* identity of the provider
|
|
||||||
* @param description
|
|
||||||
* data describing the new topology
|
|
||||||
*/
|
|
||||||
DefaultTopology(ProviderId providerId, GraphDescription description) {
|
|
||||||
super(providerId);
|
|
||||||
this.time = description.timestamp();
|
|
||||||
this.creationTime = description.creationTime();
|
|
||||||
|
|
||||||
// Build the graph
|
|
||||||
this.graph = new DefaultTopologyGraph(description.vertexes(),
|
|
||||||
description.edges());
|
|
||||||
|
|
||||||
this.clusterResults = Suppliers.memoize(() -> searchForClusters());
|
|
||||||
this.clusters = Suppliers.memoize(() -> buildTopologyClusters());
|
|
||||||
|
|
||||||
this.clusterIndexes = Suppliers.memoize(() -> buildIndexes());
|
|
||||||
|
|
||||||
this.weight = new HopCountLinkWeight(graph.getVertexes().size());
|
|
||||||
this.broadcastSets = Suppliers.memoize(() -> buildBroadcastSets());
|
|
||||||
this.infrastructurePoints = Suppliers
|
|
||||||
.memoize(() -> findInfrastructurePoints());
|
|
||||||
this.computeCost = Math.max(0, System.nanoTime() - time);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long time() {
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long creationTime() {
|
|
||||||
return creationTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long computeCost() {
|
|
||||||
return computeCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int clusterCount() {
|
|
||||||
return clusters.get().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int deviceCount() {
|
|
||||||
return graph.getVertexes().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int linkCount() {
|
|
||||||
return graph.getEdges().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ImmutableMap<DeviceId, TopologyCluster> clustersByDevice() {
|
|
||||||
return clusterIndexes.get().clustersByDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster() {
|
|
||||||
return clusterIndexes.get().devicesByCluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ImmutableSetMultimap<TopologyCluster, Link> linksByCluster() {
|
|
||||||
return clusterIndexes.get().linksByCluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the backing topology graph.
|
|
||||||
*
|
|
||||||
* @return topology graph
|
|
||||||
*/
|
|
||||||
TopologyGraph getGraph() {
|
|
||||||
return graph;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of topology clusters.
|
|
||||||
*
|
|
||||||
* @return set of clusters
|
|
||||||
*/
|
|
||||||
Set<TopologyCluster> getClusters() {
|
|
||||||
return ImmutableSet.copyOf(clusters.get().values());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the specified topology cluster.
|
|
||||||
*
|
|
||||||
* @param clusterId cluster identifier
|
|
||||||
*
|
|
||||||
* @return topology cluster
|
|
||||||
*/
|
|
||||||
TopologyCluster getCluster(ClusterId clusterId) {
|
|
||||||
return clusters.get().get(clusterId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the topology cluster that contains the given device.
|
|
||||||
*
|
|
||||||
* @param deviceId device identifier
|
|
||||||
*
|
|
||||||
* @return topology cluster
|
|
||||||
*/
|
|
||||||
TopologyCluster getCluster(DeviceId deviceId) {
|
|
||||||
return clustersByDevice().get(deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of cluster devices.
|
|
||||||
*
|
|
||||||
* @param cluster topology cluster
|
|
||||||
*
|
|
||||||
* @return cluster devices
|
|
||||||
*/
|
|
||||||
Set<DeviceId> getClusterDevices(TopologyCluster cluster) {
|
|
||||||
return devicesByCluster().get(cluster);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of cluster links.
|
|
||||||
*
|
|
||||||
* @param cluster topology cluster
|
|
||||||
*
|
|
||||||
* @return cluster links
|
|
||||||
*/
|
|
||||||
Set<Link> getClusterLinks(TopologyCluster cluster) {
|
|
||||||
return linksByCluster().get(cluster);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the given point is an infrastructure link end-point.
|
|
||||||
*
|
|
||||||
* @param connectPoint connection point
|
|
||||||
*
|
|
||||||
* @return true if infrastructure
|
|
||||||
*/
|
|
||||||
boolean isInfrastructure(ConnectPoint connectPoint) {
|
|
||||||
return infrastructurePoints.get().contains(connectPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the given point is part of a broadcast set.
|
|
||||||
*
|
|
||||||
* @param connectPoint connection point
|
|
||||||
*
|
|
||||||
* @return true if in broadcast set
|
|
||||||
*/
|
|
||||||
boolean isBroadcastPoint(ConnectPoint connectPoint) {
|
|
||||||
// Any non-infrastructure, i.e. edge points are assumed to be OK.
|
|
||||||
if (!isInfrastructure(connectPoint)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the cluster to which the device belongs.
|
|
||||||
TopologyCluster cluster = clustersByDevice().get(connectPoint.deviceId());
|
|
||||||
if (cluster == null) {
|
|
||||||
throw new IllegalArgumentException("No cluster found for device "
|
|
||||||
+ connectPoint.deviceId());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the broadcast set is null or empty, or if the point explicitly
|
|
||||||
// belongs to it, return true;
|
|
||||||
Set<ConnectPoint> points = broadcastSets.get().get(cluster.id());
|
|
||||||
return (points == null) || points.isEmpty() || points.contains(connectPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the size of the cluster broadcast set.
|
|
||||||
*
|
|
||||||
* @param clusterId cluster identifier
|
|
||||||
*
|
|
||||||
* @return size of the cluster broadcast set
|
|
||||||
*/
|
|
||||||
int broadcastSetSize(ClusterId clusterId) {
|
|
||||||
return broadcastSets.get().get(clusterId).size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the set of pre-computed shortest paths between source and
|
|
||||||
* destination devices.
|
|
||||||
*
|
|
||||||
* @param src source device
|
|
||||||
*
|
|
||||||
* @param dst destination device
|
|
||||||
*
|
|
||||||
* @return set of shortest paths
|
|
||||||
*/
|
|
||||||
Set<Path> getPaths(DeviceId src, DeviceId dst) {
|
|
||||||
return getPaths(src, dst, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes on-demand the set of shortest paths between source and
|
|
||||||
* destination devices.
|
|
||||||
*
|
|
||||||
* @param src source device
|
|
||||||
*
|
|
||||||
* @param dst destination device
|
|
||||||
*
|
|
||||||
* @param weight link weight function
|
|
||||||
*
|
|
||||||
* @return set of shortest paths
|
|
||||||
*/
|
|
||||||
Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) {
|
|
||||||
final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
|
|
||||||
final 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
|
|
||||||
return ImmutableSet.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
|
|
||||||
DIJKSTRA.search(graph, srcV, dstV, weight, ALL_PATHS);
|
|
||||||
ImmutableSet.Builder<Path> builder = ImmutableSet.builder();
|
|
||||||
for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) {
|
|
||||||
builder.add(networkPath(path));
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
return new DefaultPath(CORE_PROVIDER_ID, links, path.cost());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Searches for SCC clusters in the network topology graph using Tarjan
|
|
||||||
// algorithm.
|
|
||||||
private SCCResult<TopologyVertex, TopologyEdge> searchForClusters() {
|
|
||||||
return TARJAN.search(graph, new NoIndirectLinksWeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds the topology clusters and returns the id-cluster bindings.
|
|
||||||
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();
|
|
||||||
List<Set<TopologyEdge>> clusterEdges = results.clusterEdges();
|
|
||||||
|
|
||||||
// Scan over the lists and create a cluster from the results.
|
|
||||||
for (int i = 0, n = results.clusterCount(); i < n; i++) {
|
|
||||||
Set<TopologyVertex> vertexSet = clusterVertexes.get(i);
|
|
||||||
Set<TopologyEdge> edgeSet = clusterEdges.get(i);
|
|
||||||
|
|
||||||
ClusterId cid = ClusterId.clusterId(i);
|
|
||||||
DefaultTopologyCluster cluster = new DefaultTopologyCluster(cid,
|
|
||||||
vertexSet.size(),
|
|
||||||
edgeSet.size(),
|
|
||||||
findRoot(vertexSet));
|
|
||||||
clusterBuilder.put(cid, cluster);
|
|
||||||
}
|
|
||||||
return clusterBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finds the vertex whose device id is the lexicographical minimum in the
|
|
||||||
// specified set.
|
|
||||||
private TopologyVertex findRoot(Set<TopologyVertex> vertexSet) {
|
|
||||||
TopologyVertex minVertex = null;
|
|
||||||
for (TopologyVertex vertex : vertexSet) {
|
|
||||||
if ((minVertex == null) || (minVertex.deviceId().toString()
|
|
||||||
.compareTo(minVertex.deviceId().toString()) < 0)) {
|
|
||||||
minVertex = vertex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return minVertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Processes a map of broadcast sets for each cluster.
|
|
||||||
private ImmutableSetMultimap<ClusterId, ConnectPoint> buildBroadcastSets() {
|
|
||||||
Builder<ClusterId, ConnectPoint> builder = ImmutableSetMultimap.builder();
|
|
||||||
for (TopologyCluster cluster : clusters.get().values()) {
|
|
||||||
addClusterBroadcastSet(cluster, builder);
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finds all broadcast points for the cluster. These are those connection
|
|
||||||
// points which lie along the shortest paths between the cluster root and
|
|
||||||
// all other devices within the cluster.
|
|
||||||
private void addClusterBroadcastSet(TopologyCluster cluster, Builder<ClusterId, ConnectPoint> builder) {
|
|
||||||
// Use the graph root search results to build the broadcast set.
|
|
||||||
Result<TopologyVertex, TopologyEdge> result =
|
|
||||||
DIJKSTRA.search(graph, cluster.root(), null, weight, 1);
|
|
||||||
for (Map.Entry<TopologyVertex, Set<TopologyEdge>> entry : result.parents().entrySet()) {
|
|
||||||
TopologyVertex vertex = entry.getKey();
|
|
||||||
|
|
||||||
// Ignore any parents that lead outside the cluster.
|
|
||||||
if (clustersByDevice().get(vertex.deviceId()) != cluster) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore any back-link sets that are empty.
|
|
||||||
Set<TopologyEdge> parents = entry.getValue();
|
|
||||||
if (parents.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the first back-link source and destinations to add to the
|
|
||||||
// broadcast set.
|
|
||||||
Link link = parents.iterator().next().link();
|
|
||||||
builder.put(cluster.id(), link.src());
|
|
||||||
builder.put(cluster.id(), link.dst());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collects and returns an set of all infrastructure link end-points.
|
|
||||||
private ImmutableSet<ConnectPoint> findInfrastructurePoints() {
|
|
||||||
ImmutableSet.Builder<ConnectPoint> builder = ImmutableSet.builder();
|
|
||||||
for (TopologyEdge edge : graph.getEdges()) {
|
|
||||||
builder.add(edge.link().src());
|
|
||||||
builder.add(edge.link().dst());
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds cluster-devices, cluster-links and device-cluster indexes.
|
|
||||||
private ClusterIndexes buildIndexes() {
|
|
||||||
// Prepare the index builders
|
|
||||||
ImmutableMap.Builder<DeviceId, TopologyCluster> clusterBuilder =
|
|
||||||
ImmutableMap.builder();
|
|
||||||
ImmutableSetMultimap.Builder<TopologyCluster, DeviceId> devicesBuilder =
|
|
||||||
ImmutableSetMultimap.builder();
|
|
||||||
ImmutableSetMultimap.Builder<TopologyCluster, Link> linksBuilder =
|
|
||||||
ImmutableSetMultimap.builder();
|
|
||||||
|
|
||||||
// Now scan through all the clusters
|
|
||||||
for (TopologyCluster cluster : clusters.get().values()) {
|
|
||||||
int i = cluster.id().index();
|
|
||||||
|
|
||||||
// Scan through all the cluster vertexes.
|
|
||||||
for (TopologyVertex vertex : clusterResults.get().clusterVertexes().get(i)) {
|
|
||||||
devicesBuilder.put(cluster, vertex.deviceId());
|
|
||||||
clusterBuilder.put(vertex.deviceId(), cluster);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan through all the cluster edges.
|
|
||||||
for (TopologyEdge edge : clusterResults.get().clusterEdges().get(i)) {
|
|
||||||
linksBuilder.put(cluster, edge.link());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize all indexes.
|
|
||||||
return new ClusterIndexes(clusterBuilder.build(),
|
|
||||||
devicesBuilder.build(), linksBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link weight for measuring link cost as hop count with indirect links
|
|
||||||
// being as expensive as traversing the entire graph to assume the worst.
|
|
||||||
private static class HopCountLinkWeight implements LinkWeight {
|
|
||||||
private final int indirectLinkCost;
|
|
||||||
|
|
||||||
HopCountLinkWeight(int indirectLinkCost) {
|
|
||||||
this.indirectLinkCost = indirectLinkCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double weight(TopologyEdge edge) {
|
|
||||||
// To force preference to use direct paths first, make indirect
|
|
||||||
// links as expensive as the linear vertex traversal.
|
|
||||||
return edge.link().state() ==
|
|
||||||
ACTIVE ? (edge.link().type() ==
|
|
||||||
INDIRECT ? indirectLinkCost : 1) : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link weight for preventing traversal over indirect links.
|
|
||||||
private static class NoIndirectLinksWeight implements LinkWeight {
|
|
||||||
@Override
|
|
||||||
public double weight(TopologyEdge edge) {
|
|
||||||
return (edge.link().state() == INACTIVE)
|
|
||||||
|| (edge.link().type() == INDIRECT) ? -1 : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class ClusterIndexes {
|
|
||||||
final ImmutableMap<DeviceId, TopologyCluster> clustersByDevice;
|
|
||||||
final ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster;
|
|
||||||
final ImmutableSetMultimap<TopologyCluster, Link> linksByCluster;
|
|
||||||
|
|
||||||
public ClusterIndexes(
|
|
||||||
ImmutableMap<DeviceId, TopologyCluster> clustersByDevice,
|
|
||||||
ImmutableSetMultimap<TopologyCluster, DeviceId> devicesByCluster,
|
|
||||||
ImmutableSetMultimap<TopologyCluster, Link> linksByCluster) {
|
|
||||||
this.clustersByDevice = clustersByDevice;
|
|
||||||
this.devicesByCluster = devicesByCluster;
|
|
||||||
this.linksByCluster = linksByCluster;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return toStringHelper(this)
|
|
||||||
.add("time", time)
|
|
||||||
.add("created", creationTime)
|
|
||||||
.add("computeCost", computeCost)
|
|
||||||
.add("clusters", clusterCount())
|
|
||||||
.add("devices", deviceCount())
|
|
||||||
.add("links", linkCount()).toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,6 +19,7 @@ import org.apache.felix.scr.annotations.Activate;
|
|||||||
import org.apache.felix.scr.annotations.Component;
|
import org.apache.felix.scr.annotations.Component;
|
||||||
import org.apache.felix.scr.annotations.Deactivate;
|
import org.apache.felix.scr.annotations.Deactivate;
|
||||||
import org.apache.felix.scr.annotations.Service;
|
import org.apache.felix.scr.annotations.Service;
|
||||||
|
import org.onosproject.common.DefaultTopology;
|
||||||
import org.onosproject.event.Event;
|
import org.onosproject.event.Event;
|
||||||
import org.onosproject.net.ConnectPoint;
|
import org.onosproject.net.ConnectPoint;
|
||||||
import org.onosproject.net.DeviceId;
|
import org.onosproject.net.DeviceId;
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 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.store.topology.impl;
|
|
||||||
|
|
||||||
import org.onlab.graph.AdjacencyListsGraph;
|
|
||||||
import org.onosproject.net.topology.TopologyEdge;
|
|
||||||
import org.onosproject.net.topology.TopologyGraph;
|
|
||||||
import org.onosproject.net.topology.TopologyVertex;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default implementation of an immutable topology graph based on a generic
|
|
||||||
* implementation of adjacency lists graph.
|
|
||||||
*/
|
|
||||||
public class DefaultTopologyGraph
|
|
||||||
extends AdjacencyListsGraph<TopologyVertex, TopologyEdge>
|
|
||||||
implements TopologyGraph {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a topology graph comprising of the specified vertexes and edges.
|
|
||||||
*
|
|
||||||
* @param vertexes set of graph vertexes
|
|
||||||
* @param edges set of graph edges
|
|
||||||
*/
|
|
||||||
public DefaultTopologyGraph(Set<TopologyVertex> vertexes, Set<TopologyEdge> edges) {
|
|
||||||
super(vertexes, edges);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.onosproject.store.topology.impl;
|
package org.onosproject.store.topology.impl;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
|
||||||
import static org.slf4j.LoggerFactory.getLogger;
|
import static org.slf4j.LoggerFactory.getLogger;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -25,6 +27,7 @@ import org.apache.felix.scr.annotations.Activate;
|
|||||||
import org.apache.felix.scr.annotations.Component;
|
import org.apache.felix.scr.annotations.Component;
|
||||||
import org.apache.felix.scr.annotations.Deactivate;
|
import org.apache.felix.scr.annotations.Deactivate;
|
||||||
import org.apache.felix.scr.annotations.Service;
|
import org.apache.felix.scr.annotations.Service;
|
||||||
|
import org.onosproject.common.DefaultTopology;
|
||||||
import org.onosproject.event.Event;
|
import org.onosproject.event.Event;
|
||||||
import org.onosproject.net.ConnectPoint;
|
import org.onosproject.net.ConnectPoint;
|
||||||
import org.onosproject.net.Device;
|
import org.onosproject.net.Device;
|
||||||
@ -48,23 +51,23 @@ import org.slf4j.Logger;
|
|||||||
/**
|
/**
|
||||||
* Manages inventory of topology snapshots using trivial in-memory
|
* Manages inventory of topology snapshots using trivial in-memory
|
||||||
* structures implementation.
|
* structures implementation.
|
||||||
*
|
* <p>
|
||||||
* Note: This component is not distributed per-se. It runs on every
|
* Note: This component is not distributed per-se. It runs on every
|
||||||
* instance and feeds off of other distributed stores.
|
* instance and feeds off of other distributed stores.
|
||||||
*/
|
*/
|
||||||
@Component(immediate = true)
|
@Component(immediate = true)
|
||||||
@Service
|
@Service
|
||||||
public class DistributedTopologyStore
|
public class DistributedTopologyStore
|
||||||
extends AbstractStore<TopologyEvent, TopologyStoreDelegate>
|
extends AbstractStore<TopologyEvent, TopologyStoreDelegate>
|
||||||
implements TopologyStore {
|
implements TopologyStore {
|
||||||
|
|
||||||
private final Logger log = getLogger(getClass());
|
private final Logger log = getLogger(getClass());
|
||||||
|
|
||||||
private volatile DefaultTopology current =
|
private volatile DefaultTopology current =
|
||||||
new DefaultTopology(ProviderId.NONE,
|
new DefaultTopology(ProviderId.NONE,
|
||||||
new DefaultGraphDescription(0L,
|
new DefaultGraphDescription(0L, 0L,
|
||||||
Collections.<Device>emptyList(),
|
Collections.<Device>emptyList(),
|
||||||
Collections.<Link>emptyList()));
|
Collections.<Link>emptyList()));
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
public void activate() {
|
public void activate() {
|
||||||
@ -75,6 +78,7 @@ implements TopologyStore {
|
|||||||
public void deactivate() {
|
public void deactivate() {
|
||||||
log.info("Stopped");
|
log.info("Stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Topology currentTopology() {
|
public Topology currentTopology() {
|
||||||
return current;
|
return current;
|
||||||
@ -118,7 +122,7 @@ implements TopologyStore {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
|
public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
|
||||||
LinkWeight weight) {
|
LinkWeight weight) {
|
||||||
return defaultTopology(topology).getPaths(src, dst, weight);
|
return defaultTopology(topology).getPaths(src, dst, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +138,8 @@ implements TopologyStore {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopologyEvent updateTopology(ProviderId providerId,
|
public TopologyEvent updateTopology(ProviderId providerId,
|
||||||
GraphDescription graphDescription,
|
GraphDescription graphDescription,
|
||||||
List<Event> reasons) {
|
List<Event> reasons) {
|
||||||
// First off, make sure that what we're given is indeed newer than
|
// First off, make sure that what we're given is indeed newer than
|
||||||
// what we already have.
|
// what we already have.
|
||||||
if (current != null && graphDescription.timestamp() < current.time()) {
|
if (current != null && graphDescription.timestamp() < current.time()) {
|
||||||
@ -149,18 +153,15 @@ implements TopologyStore {
|
|||||||
// Promote the new topology to current and return a ready-to-send event.
|
// Promote the new topology to current and return a ready-to-send event.
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
current = newTopology;
|
current = newTopology;
|
||||||
return new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED,
|
return new TopologyEvent(TOPOLOGY_CHANGED, current, reasons);
|
||||||
current, reasons);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validates the specified topology and returns it as a default
|
// Validates the specified topology and returns it as a default
|
||||||
private DefaultTopology defaultTopology(Topology topology) {
|
private DefaultTopology defaultTopology(Topology topology) {
|
||||||
if (topology instanceof DefaultTopology) {
|
checkArgument(topology instanceof DefaultTopology,
|
||||||
return (DefaultTopology) topology;
|
"Topology class %s not supported", topology.getClass());
|
||||||
}
|
return (DefaultTopology) topology;
|
||||||
throw new IllegalArgumentException("Topology class " + topology.getClass() +
|
|
||||||
" not supported");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user