Committed by
Gerrit Code Review
ONOS-3515 Added ability to configure different link-weight functions as defaults…
…; or inject custom ones. ONOS-3516 Added ability to inject alternate graph path search algorithms. Change-Id: If5831c198a831ae79a9933fc794eb7deab776e2f
Showing
13 changed files
with
508 additions
and
64 deletions
... | @@ -25,7 +25,6 @@ package org.onosproject.net; | ... | @@ -25,7 +25,6 @@ package org.onosproject.net; |
25 | */ | 25 | */ |
26 | public final class AnnotationKeys { | 26 | public final class AnnotationKeys { |
27 | 27 | ||
28 | - | ||
29 | // Prohibit instantiation | 28 | // Prohibit instantiation |
30 | private AnnotationKeys() { | 29 | private AnnotationKeys() { |
31 | } | 30 | } |
... | @@ -81,6 +80,12 @@ public final class AnnotationKeys { | ... | @@ -81,6 +80,12 @@ public final class AnnotationKeys { |
81 | public static final String DURABLE = "durable"; | 80 | public static final String DURABLE = "durable"; |
82 | 81 | ||
83 | /** | 82 | /** |
83 | + * Annotation key for link metric; used by | ||
84 | + * {@link org.onosproject.net.topology.MetricLinkWeight} function. | ||
85 | + */ | ||
86 | + public static final String METRIC = "metric"; | ||
87 | + | ||
88 | + /** | ||
84 | * Annotation key for latency. | 89 | * Annotation key for latency. |
85 | * | 90 | * |
86 | * @deprecated since Cardinal | 91 | * @deprecated since Cardinal |
... | @@ -112,8 +117,14 @@ public final class AnnotationKeys { | ... | @@ -112,8 +117,14 @@ public final class AnnotationKeys { |
112 | */ | 117 | */ |
113 | public static final String ROUTER_ID = "routerId"; | 118 | public static final String ROUTER_ID = "routerId"; |
114 | 119 | ||
120 | + /** | ||
121 | + * Annotation key for the static lambda. | ||
122 | + */ | ||
115 | public static final String STATIC_LAMBDA = "staticLambda"; | 123 | public static final String STATIC_LAMBDA = "staticLambda"; |
116 | 124 | ||
125 | + /** | ||
126 | + * Annotation key for the static port. | ||
127 | + */ | ||
117 | public static final String STATIC_PORT = "staticPort"; | 128 | public static final String STATIC_PORT = "staticPort"; |
118 | 129 | ||
119 | /** | 130 | /** | ... | ... |
... | @@ -15,22 +15,32 @@ | ... | @@ -15,22 +15,32 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.net.config.basics; | 16 | package org.onosproject.net.config.basics; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
18 | import org.onosproject.net.Link; | 19 | import org.onosproject.net.Link; |
19 | import org.onosproject.net.LinkKey; | 20 | import org.onosproject.net.LinkKey; |
20 | -import com.fasterxml.jackson.databind.JsonNode; | ||
21 | 21 | ||
22 | import java.time.Duration; | 22 | import java.time.Duration; |
23 | 23 | ||
24 | +import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL; | ||
25 | + | ||
24 | /** | 26 | /** |
25 | * Basic configuration for network infrastructure link. | 27 | * Basic configuration for network infrastructure link. |
26 | */ | 28 | */ |
27 | public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { | 29 | public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { |
28 | 30 | ||
29 | public static final String TYPE = "type"; | 31 | public static final String TYPE = "type"; |
32 | + public static final String METRIC = "metric"; | ||
30 | public static final String LATENCY = "latency"; | 33 | public static final String LATENCY = "latency"; |
31 | public static final String BANDWIDTH = "bandwidth"; | 34 | public static final String BANDWIDTH = "bandwidth"; |
32 | public static final String IS_DURABLE = "durable"; | 35 | public static final String IS_DURABLE = "durable"; |
33 | 36 | ||
37 | + @Override | ||
38 | + public boolean isValid() { | ||
39 | + return hasOnlyFields(TYPE, METRIC, LATENCY, BANDWIDTH, IS_DURABLE) && | ||
40 | + isNumber(METRIC, OPTIONAL) && isNumber(LATENCY, OPTIONAL) && | ||
41 | + isNumber(BANDWIDTH, OPTIONAL); | ||
42 | + } | ||
43 | + | ||
34 | /** | 44 | /** |
35 | * Returns the link type. | 45 | * Returns the link type. |
36 | * | 46 | * |
... | @@ -51,6 +61,27 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { | ... | @@ -51,6 +61,27 @@ public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> { |
51 | } | 61 | } |
52 | 62 | ||
53 | /** | 63 | /** |
64 | + * Returns link metric value for use by | ||
65 | + * {@link org.onosproject.net.topology.MetricLinkWeight} function. | ||
66 | + * | ||
67 | + * @return link metric; -1 if not set | ||
68 | + */ | ||
69 | + public double metric() { | ||
70 | + return get(METRIC, -1); | ||
71 | + } | ||
72 | + | ||
73 | + /** | ||
74 | + * Sets the link metric for use by | ||
75 | + * {@link org.onosproject.net.topology.MetricLinkWeight} function. | ||
76 | + * | ||
77 | + * @param metric new metric; null to clear | ||
78 | + * @return self | ||
79 | + */ | ||
80 | + public BasicLinkConfig metric(Double metric) { | ||
81 | + return (BasicLinkConfig) setOrClear(METRIC, metric); | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
54 | * Returns link latency in terms of nanos. | 85 | * Returns link latency in terms of nanos. |
55 | * | 86 | * |
56 | * @return link latency; -1 if not set | 87 | * @return link latency; -1 if not set | ... | ... |
1 | +/* | ||
2 | + * Copyright 2014-2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.net.topology; | ||
18 | + | ||
19 | +import org.onlab.util.GeoLocation; | ||
20 | +import org.onosproject.net.AnnotationKeys; | ||
21 | +import org.onosproject.net.Annotations; | ||
22 | +import org.onosproject.net.Device; | ||
23 | +import org.onosproject.net.DeviceId; | ||
24 | +import org.onosproject.net.device.DeviceService; | ||
25 | + | ||
26 | +import static java.lang.Double.MAX_VALUE; | ||
27 | + | ||
28 | +/** | ||
29 | + * Link weight for measuring link cost using the geo distance between link | ||
30 | + * vertices as determined by the element longitude/latitude annotation. | ||
31 | + */ | ||
32 | +public class GeoDistanceLinkWeight implements LinkWeight { | ||
33 | + | ||
34 | + private static final double MAX_KM = 40_075 / 2.0; | ||
35 | + | ||
36 | + private final DeviceService deviceService; | ||
37 | + | ||
38 | + /** | ||
39 | + * Creates a new link-weight with access to the specified device service. | ||
40 | + * | ||
41 | + * @param deviceService device service reference | ||
42 | + */ | ||
43 | + public GeoDistanceLinkWeight(DeviceService deviceService) { | ||
44 | + this.deviceService = deviceService; | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public double weight(TopologyEdge edge) { | ||
49 | + GeoLocation src = getLocation(edge.link().src().deviceId()); | ||
50 | + GeoLocation dst = getLocation(edge.link().dst().deviceId()); | ||
51 | + return src != null && dst != null ? src.kilometersTo(dst) : MAX_KM; | ||
52 | + } | ||
53 | + | ||
54 | + private GeoLocation getLocation(DeviceId deviceId) { | ||
55 | + Device d = deviceService.getDevice(deviceId); | ||
56 | + Annotations a = d != null ? d.annotations() : null; | ||
57 | + double latitude = getDouble(a, AnnotationKeys.LATITUDE); | ||
58 | + double longitude = getDouble(a, AnnotationKeys.LONGITUDE); | ||
59 | + return latitude == MAX_VALUE || longitude == MAX_VALUE ? null : | ||
60 | + new GeoLocation(latitude, longitude); | ||
61 | + } | ||
62 | + | ||
63 | + private double getDouble(Annotations a, String key) { | ||
64 | + String value = a != null ? a.value(key) : null; | ||
65 | + try { | ||
66 | + return value != null ? Double.parseDouble(value) : MAX_VALUE; | ||
67 | + } catch (NumberFormatException e) { | ||
68 | + return MAX_VALUE; | ||
69 | + } | ||
70 | + } | ||
71 | +} | ||
72 | + |
1 | +package org.onosproject.net.topology; | ||
2 | + | ||
3 | +import static org.onosproject.net.Link.State.ACTIVE; | ||
4 | +import static org.onosproject.net.Link.Type.INDIRECT; | ||
5 | + | ||
6 | +/** | ||
7 | + * Link weight for measuring link cost as hop count with indirect links | ||
8 | + * being as expensive as traversing the entire graph to assume the worst. | ||
9 | + */ | ||
10 | +public class HopCountLinkWeight implements LinkWeight { | ||
11 | + private final int indirectLinkCost; | ||
12 | + | ||
13 | + /** | ||
14 | + * Creates a new hop-count weight. | ||
15 | + */ | ||
16 | + public HopCountLinkWeight() { | ||
17 | + this.indirectLinkCost = Short.MAX_VALUE; | ||
18 | + } | ||
19 | + | ||
20 | + /** | ||
21 | + * Creates a new hop-count weight with the specified cost of indirect links. | ||
22 | + */ | ||
23 | + public HopCountLinkWeight(int indirectLinkCost) { | ||
24 | + this.indirectLinkCost = indirectLinkCost; | ||
25 | + } | ||
26 | + | ||
27 | + @Override | ||
28 | + public double weight(TopologyEdge edge) { | ||
29 | + // To force preference to use direct paths first, make indirect | ||
30 | + // links as expensive as the linear vertex traversal. | ||
31 | + return edge.link().state() == | ||
32 | + ACTIVE ? (edge.link().type() == | ||
33 | + INDIRECT ? indirectLinkCost : 1) : -1; | ||
34 | + } | ||
35 | +} | ||
36 | + |
1 | +/* | ||
2 | + * Copyright 2014-2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.net.topology; | ||
18 | + | ||
19 | +import org.onosproject.net.AnnotationKeys; | ||
20 | + | ||
21 | +/** | ||
22 | + * Link weight for measuring link cost using the link metric annotation. | ||
23 | + */ | ||
24 | +public class MetricLinkWeight implements LinkWeight { | ||
25 | + | ||
26 | + @Override | ||
27 | + public double weight(TopologyEdge edge) { | ||
28 | + String v = edge.link().annotations().value(AnnotationKeys.METRIC); | ||
29 | + try { | ||
30 | + return v != null ? Double.parseDouble(v) : 1; | ||
31 | + } catch (NumberFormatException e) { | ||
32 | + return 1; | ||
33 | + } | ||
34 | + } | ||
35 | +} | ||
36 | + |
1 | +/* | ||
2 | + * Copyright 2014-2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.net.topology; | ||
18 | + | ||
19 | +import org.onlab.graph.GraphPathSearch; | ||
20 | + | ||
21 | +/** | ||
22 | + * Provides administrative abilities to tailor the path service behaviours. | ||
23 | + */ | ||
24 | +public interface PathAdminService { | ||
25 | + | ||
26 | + /** | ||
27 | + * Sets the specified link-weight function to be used as a default. | ||
28 | + * If null is specified, the builtin default hop-count link-weight will be | ||
29 | + * used. | ||
30 | + * | ||
31 | + * @param linkWeight default link-weight function | ||
32 | + */ | ||
33 | + void setDefaultLinkWeight(LinkWeight linkWeight); | ||
34 | + | ||
35 | + /** | ||
36 | + * Sets the specified graph path search algorightm to be used as a default. | ||
37 | + * If null is specified, the builtin default all-shortest-paths Dijkstra | ||
38 | + * algorithm will be used. | ||
39 | + * | ||
40 | + * @param graphPathSearch default graph path search algorithm | ||
41 | + */ | ||
42 | + void setDefaultGraphPathSearch(GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch); | ||
43 | + | ||
44 | +} |
... | @@ -30,8 +30,9 @@ import java.util.Set; | ... | @@ -30,8 +30,9 @@ import java.util.Set; |
30 | public interface PathService { | 30 | public interface PathService { |
31 | 31 | ||
32 | /** | 32 | /** |
33 | - * Returns the set of all shortest paths, precomputed in terms of hop-count, | 33 | + * Returns the set of all shortest paths between the specified source and |
34 | - * between the specified source and destination elements. | 34 | + * destination elements. The path is computed using the default edge-weight |
35 | + * function, which by default is hop-count. | ||
35 | * | 36 | * |
36 | * @param src source element | 37 | * @param src source element |
37 | * @param dst destination element | 38 | * @param dst destination element |
... | @@ -40,9 +41,9 @@ public interface PathService { | ... | @@ -40,9 +41,9 @@ public interface PathService { |
40 | Set<Path> getPaths(ElementId src, ElementId dst); | 41 | Set<Path> getPaths(ElementId src, ElementId dst); |
41 | 42 | ||
42 | /** | 43 | /** |
43 | - * Returns the set of all shortest paths, computed using the supplied | 44 | + * Returns the set of all shortest paths between the specified source and |
44 | - * edge-weight entity, between the specified source and destination | 45 | + * destination network elements. The path is computed using the supplied |
45 | - * network elements. | 46 | + * edge-weight function. |
46 | * | 47 | * |
47 | * @param src source element | 48 | * @param src source element |
48 | * @param dst destination element | 49 | * @param dst destination element |
... | @@ -52,8 +53,9 @@ public interface PathService { | ... | @@ -52,8 +53,9 @@ public interface PathService { |
52 | Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight); | 53 | Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight); |
53 | 54 | ||
54 | /** | 55 | /** |
55 | - * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count, | 56 | + * Returns the set of all disjoint shortest path pairs between the |
56 | - * between the specified source and destination devices. | 57 | + * specified source and destination elements. The path is computed using |
58 | + * the default edge-weight function, which by default is hop-count. | ||
57 | * | 59 | * |
58 | * @param src source device | 60 | * @param src source device |
59 | * @param dst destination device | 61 | * @param dst destination device |
... | @@ -62,8 +64,9 @@ public interface PathService { | ... | @@ -62,8 +64,9 @@ public interface PathService { |
62 | Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst); | 64 | Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst); |
63 | 65 | ||
64 | /** | 66 | /** |
65 | - * Returns the set of all disjoint shortest path pairs, computed using the supplied | 67 | + * Returns the set of all disjoint shortest path pairs between the |
66 | - * edge-weight entity, between the specified source and destination devices. | 68 | + * specified source and destination elements. The path is computed using |
69 | + * the supplied edge-weight function. | ||
67 | * | 70 | * |
68 | * @param src source device | 71 | * @param src source device |
69 | * @param dst destination device | 72 | * @param dst destination device |
... | @@ -74,8 +77,10 @@ public interface PathService { | ... | @@ -74,8 +77,10 @@ public interface PathService { |
74 | LinkWeight weight); | 77 | LinkWeight weight); |
75 | 78 | ||
76 | /** | 79 | /** |
77 | - * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count, | 80 | + * Returns the set of all disjoint shortest path pairs between the |
78 | - * between the specified source and destination devices. | 81 | + * specified source and destination elements and taking into consideration |
82 | + * the provided risk profile. The path is computed using the default | ||
83 | + * edge-weight function, which by default is hop-count. | ||
79 | * | 84 | * |
80 | * @param src source device | 85 | * @param src source device |
81 | * @param dst destination device | 86 | * @param dst destination device |
... | @@ -86,8 +91,10 @@ public interface PathService { | ... | @@ -86,8 +91,10 @@ public interface PathService { |
86 | Map<Link, Object> riskProfile); | 91 | Map<Link, Object> riskProfile); |
87 | 92 | ||
88 | /** | 93 | /** |
89 | - * Returns the set of all disjoint shortest path pairs, precomputed in terms of hop-count, | 94 | + * Returns the set of all disjoint shortest path pairs between the |
90 | - * between the specified source and destination devices. | 95 | + * specified source and destination elements and taking into consideration |
96 | + * the provided risk profile. The path is computed using the supplied | ||
97 | + * edge-weight function. | ||
91 | * | 98 | * |
92 | * @param src source device | 99 | * @param src source device |
93 | * @param dst destination device | 100 | * @param dst destination device |
... | @@ -96,6 +103,7 @@ public interface PathService { | ... | @@ -96,6 +103,7 @@ public interface PathService { |
96 | * @return set of all shortest paths between the two devices | 103 | * @return set of all shortest paths between the two devices |
97 | */ | 104 | */ |
98 | Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, | 105 | Set<DisjointPath> getDisjointPaths(ElementId src, ElementId dst, |
99 | - LinkWeight weight, Map<Link, Object> riskProfile); | 106 | + LinkWeight weight, |
107 | + Map<Link, Object> riskProfile); | ||
100 | 108 | ||
101 | } | 109 | } | ... | ... |
... | @@ -43,12 +43,15 @@ import org.onosproject.net.topology.ClusterId; | ... | @@ -43,12 +43,15 @@ import org.onosproject.net.topology.ClusterId; |
43 | import org.onosproject.net.topology.DefaultTopologyCluster; | 43 | import org.onosproject.net.topology.DefaultTopologyCluster; |
44 | import org.onosproject.net.topology.DefaultTopologyVertex; | 44 | import org.onosproject.net.topology.DefaultTopologyVertex; |
45 | import org.onosproject.net.topology.GraphDescription; | 45 | import org.onosproject.net.topology.GraphDescription; |
46 | +import org.onosproject.net.topology.HopCountLinkWeight; | ||
46 | import org.onosproject.net.topology.LinkWeight; | 47 | import org.onosproject.net.topology.LinkWeight; |
47 | import org.onosproject.net.topology.Topology; | 48 | import org.onosproject.net.topology.Topology; |
48 | import org.onosproject.net.topology.TopologyCluster; | 49 | import org.onosproject.net.topology.TopologyCluster; |
49 | import org.onosproject.net.topology.TopologyEdge; | 50 | import org.onosproject.net.topology.TopologyEdge; |
50 | import org.onosproject.net.topology.TopologyGraph; | 51 | import org.onosproject.net.topology.TopologyGraph; |
51 | import org.onosproject.net.topology.TopologyVertex; | 52 | import org.onosproject.net.topology.TopologyVertex; |
53 | +import org.slf4j.Logger; | ||
54 | +import org.slf4j.LoggerFactory; | ||
52 | 55 | ||
53 | import java.util.HashMap; | 56 | import java.util.HashMap; |
54 | import java.util.List; | 57 | import java.util.List; |
... | @@ -61,7 +64,6 @@ import static com.google.common.base.Preconditions.checkArgument; | ... | @@ -61,7 +64,6 @@ import static com.google.common.base.Preconditions.checkArgument; |
61 | import static org.onlab.graph.GraphPathSearch.ALL_PATHS; | 64 | import static org.onlab.graph.GraphPathSearch.ALL_PATHS; |
62 | import static org.onlab.util.Tools.isNullOrEmpty; | 65 | import static org.onlab.util.Tools.isNullOrEmpty; |
63 | import static org.onosproject.core.CoreService.CORE_PROVIDER_ID; | 66 | import static org.onosproject.core.CoreService.CORE_PROVIDER_ID; |
64 | -import static org.onosproject.net.Link.State.ACTIVE; | ||
65 | import static org.onosproject.net.Link.State.INACTIVE; | 67 | import static org.onosproject.net.Link.State.INACTIVE; |
66 | import static org.onosproject.net.Link.Type.INDIRECT; | 68 | import static org.onosproject.net.Link.Type.INDIRECT; |
67 | 69 | ||
... | @@ -71,18 +73,22 @@ import static org.onosproject.net.Link.Type.INDIRECT; | ... | @@ -71,18 +73,22 @@ import static org.onosproject.net.Link.Type.INDIRECT; |
71 | */ | 73 | */ |
72 | public class DefaultTopology extends AbstractModel implements Topology { | 74 | public class DefaultTopology extends AbstractModel implements Topology { |
73 | 75 | ||
76 | + private static final Logger log = LoggerFactory.getLogger(DefaultTopology.class); | ||
77 | + | ||
74 | private static final DijkstraGraphSearch<TopologyVertex, TopologyEdge> DIJKSTRA = new DijkstraGraphSearch<>(); | 78 | private static final DijkstraGraphSearch<TopologyVertex, TopologyEdge> DIJKSTRA = new DijkstraGraphSearch<>(); |
75 | private static final TarjanGraphSearch<TopologyVertex, TopologyEdge> TARJAN = new TarjanGraphSearch<>(); | 79 | private static final TarjanGraphSearch<TopologyVertex, TopologyEdge> TARJAN = new TarjanGraphSearch<>(); |
76 | - private static final SuurballeGraphSearch<TopologyVertex, TopologyEdge> SUURBALLE = | 80 | + private static final SuurballeGraphSearch<TopologyVertex, TopologyEdge> SUURBALLE = new SuurballeGraphSearch<>(); |
77 | - new SuurballeGraphSearch<>(); | ||
78 | 81 | ||
82 | + private static LinkWeight defaultLinkWeight = null; | ||
83 | + private static GraphPathSearch<TopologyVertex, TopologyEdge> defaultGraphPathSearch = null; | ||
79 | 84 | ||
80 | private final long time; | 85 | private final long time; |
81 | private final long creationTime; | 86 | private final long creationTime; |
82 | private final long computeCost; | 87 | private final long computeCost; |
83 | private final TopologyGraph graph; | 88 | private final TopologyGraph graph; |
84 | 89 | ||
85 | - private final LinkWeight weight; | 90 | + private final LinkWeight hopCountWeight; |
91 | + | ||
86 | private final Supplier<SccResult<TopologyVertex, TopologyEdge>> clusterResults; | 92 | private final Supplier<SccResult<TopologyVertex, TopologyEdge>> clusterResults; |
87 | private final Supplier<ImmutableMap<ClusterId, TopologyCluster>> clusters; | 93 | private final Supplier<ImmutableMap<ClusterId, TopologyCluster>> clusters; |
88 | private final Supplier<ImmutableSet<ConnectPoint>> infrastructurePoints; | 94 | private final Supplier<ImmutableSet<ConnectPoint>> infrastructurePoints; |
... | @@ -91,6 +97,30 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -91,6 +97,30 @@ public class DefaultTopology extends AbstractModel implements Topology { |
91 | private final Supplier<ClusterIndexes> clusterIndexes; | 97 | private final Supplier<ClusterIndexes> clusterIndexes; |
92 | 98 | ||
93 | /** | 99 | /** |
100 | + * Sets the default link-weight to be used when computing paths. If null is | ||
101 | + * specified, the builtin default link-weight measuring hop-counts will be | ||
102 | + * used. | ||
103 | + * | ||
104 | + * @param linkWeight new default link-weight | ||
105 | + */ | ||
106 | + public static void setDefaultLinkWeight(LinkWeight linkWeight) { | ||
107 | + log.info("Setting new default link-weight function to {}", linkWeight); | ||
108 | + defaultLinkWeight = linkWeight; | ||
109 | + } | ||
110 | + | ||
111 | + /** | ||
112 | + * Sets the default lpath search algorighm to be used when computing paths. | ||
113 | + * If null is specified, the builtin default Dijkstra will be used. | ||
114 | + * | ||
115 | + * @param graphPathSearch new default algorithm | ||
116 | + */ | ||
117 | + public static void setDefaultGraphPathSearch(GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch) { | ||
118 | + log.info("Setting new default graph path algorithm to {}", graphPathSearch); | ||
119 | + defaultGraphPathSearch = graphPathSearch; | ||
120 | + } | ||
121 | + | ||
122 | + | ||
123 | + /** | ||
94 | * Creates a topology descriptor attributed to the specified provider. | 124 | * Creates a topology descriptor attributed to the specified provider. |
95 | * | 125 | * |
96 | * @param providerId identity of the provider | 126 | * @param providerId identity of the provider |
... | @@ -113,7 +143,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -113,7 +143,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
113 | 143 | ||
114 | this.clusterIndexes = Suppliers.memoize(() -> buildIndexes()); | 144 | this.clusterIndexes = Suppliers.memoize(() -> buildIndexes()); |
115 | 145 | ||
116 | - this.weight = new HopCountLinkWeight(graph.getVertexes().size()); | 146 | + this.hopCountWeight = new HopCountLinkWeight(graph.getVertexes().size()); |
117 | this.broadcastSets = Suppliers.memoize(() -> buildBroadcastSets()); | 147 | this.broadcastSets = Suppliers.memoize(() -> buildBroadcastSets()); |
118 | this.infrastructurePoints = Suppliers.memoize(() -> findInfrastructurePoints()); | 148 | this.infrastructurePoints = Suppliers.memoize(() -> findInfrastructurePoints()); |
119 | this.computeCost = Math.max(0, System.nanoTime() - time); | 149 | this.computeCost = Math.max(0, System.nanoTime() - time); |
... | @@ -294,7 +324,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -294,7 +324,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
294 | * @return set of shortest paths | 324 | * @return set of shortest paths |
295 | */ | 325 | */ |
296 | public Set<Path> getPaths(DeviceId src, DeviceId dst) { | 326 | public Set<Path> getPaths(DeviceId src, DeviceId dst) { |
297 | - return getPaths(src, dst, null); | 327 | + return getPaths(src, dst, linkWeight()); |
298 | } | 328 | } |
299 | 329 | ||
300 | /** | 330 | /** |
... | @@ -307,8 +337,8 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -307,8 +337,8 @@ public class DefaultTopology extends AbstractModel implements Topology { |
307 | * @return set of shortest paths | 337 | * @return set of shortest paths |
308 | */ | 338 | */ |
309 | public Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) { | 339 | public Set<Path> getPaths(DeviceId src, DeviceId dst, LinkWeight weight) { |
310 | - final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); | 340 | + DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); |
311 | - final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst); | 341 | + DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst); |
312 | Set<TopologyVertex> vertices = graph.getVertexes(); | 342 | Set<TopologyVertex> vertices = graph.getVertexes(); |
313 | if (!vertices.contains(srcV) || !vertices.contains(dstV)) { | 343 | if (!vertices.contains(srcV) || !vertices.contains(dstV)) { |
314 | // src or dst not part of the current graph | 344 | // src or dst not part of the current graph |
... | @@ -316,7 +346,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -316,7 +346,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
316 | } | 346 | } |
317 | 347 | ||
318 | GraphPathSearch.Result<TopologyVertex, TopologyEdge> result = | 348 | GraphPathSearch.Result<TopologyVertex, TopologyEdge> result = |
319 | - DIJKSTRA.search(graph, srcV, dstV, weight, ALL_PATHS); | 349 | + graphPathSearch().search(graph, srcV, dstV, weight, ALL_PATHS); |
320 | ImmutableSet.Builder<Path> builder = ImmutableSet.builder(); | 350 | ImmutableSet.Builder<Path> builder = ImmutableSet.builder(); |
321 | for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) { | 351 | for (org.onlab.graph.Path<TopologyVertex, TopologyEdge> path : result.paths()) { |
322 | builder.add(networkPath(path)); | 352 | builder.add(networkPath(path)); |
... | @@ -334,7 +364,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -334,7 +364,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
334 | * @return set of shortest disjoint path pairs | 364 | * @return set of shortest disjoint path pairs |
335 | */ | 365 | */ |
336 | public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) { | 366 | public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst) { |
337 | - return getDisjointPaths(src, dst, (LinkWeight) null); | 367 | + return getDisjointPaths(src, dst, linkWeight()); |
338 | } | 368 | } |
339 | 369 | ||
340 | /** | 370 | /** |
... | @@ -347,8 +377,8 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -347,8 +377,8 @@ public class DefaultTopology extends AbstractModel implements Topology { |
347 | * @return set of disjoint shortest path pairs | 377 | * @return set of disjoint shortest path pairs |
348 | */ | 378 | */ |
349 | public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight) { | 379 | public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, LinkWeight weight) { |
350 | - final DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); | 380 | + DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); |
351 | - final DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst); | 381 | + DefaultTopologyVertex dstV = new DefaultTopologyVertex(dst); |
352 | Set<TopologyVertex> vertices = graph.getVertexes(); | 382 | Set<TopologyVertex> vertices = graph.getVertexes(); |
353 | if (!vertices.contains(srcV) || !vertices.contains(dstV)) { | 383 | if (!vertices.contains(srcV) || !vertices.contains(dstV)) { |
354 | // src or dst not part of the current graph | 384 | // src or dst not part of the current graph |
... | @@ -438,7 +468,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -438,7 +468,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
438 | * @return set of shortest disjoint paths | 468 | * @return set of shortest disjoint paths |
439 | */ | 469 | */ |
440 | public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) { | 470 | public Set<DisjointPath> getDisjointPaths(DeviceId src, DeviceId dst, Map<Link, Object> riskProfile) { |
441 | - return getDisjointPaths(src, dst, null, riskProfile); | 471 | + return getDisjointPaths(src, dst, linkWeight(), riskProfile); |
442 | } | 472 | } |
443 | 473 | ||
444 | // Converts graph path to a network path with the same cost. | 474 | // Converts graph path to a network path with the same cost. |
... | @@ -499,8 +529,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -499,8 +529,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
499 | 529 | ||
500 | // Processes a map of broadcast sets for each cluster. | 530 | // Processes a map of broadcast sets for each cluster. |
501 | private ImmutableSetMultimap<ClusterId, ConnectPoint> buildBroadcastSets() { | 531 | private ImmutableSetMultimap<ClusterId, ConnectPoint> buildBroadcastSets() { |
502 | - Builder<ClusterId, ConnectPoint> builder = ImmutableSetMultimap | 532 | + Builder<ClusterId, ConnectPoint> builder = ImmutableSetMultimap.builder(); |
503 | - .builder(); | ||
504 | for (TopologyCluster cluster : clusters.get().values()) { | 533 | for (TopologyCluster cluster : clusters.get().values()) { |
505 | addClusterBroadcastSet(cluster, builder); | 534 | addClusterBroadcastSet(cluster, builder); |
506 | } | 535 | } |
... | @@ -512,7 +541,7 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -512,7 +541,7 @@ public class DefaultTopology extends AbstractModel implements Topology { |
512 | // all other devices within the cluster. | 541 | // all other devices within the cluster. |
513 | private void addClusterBroadcastSet(TopologyCluster cluster, Builder<ClusterId, ConnectPoint> builder) { | 542 | private void addClusterBroadcastSet(TopologyCluster cluster, Builder<ClusterId, ConnectPoint> builder) { |
514 | // Use the graph root search results to build the broadcast set. | 543 | // Use the graph root search results to build the broadcast set. |
515 | - Result<TopologyVertex, TopologyEdge> result = DIJKSTRA.search(graph, cluster.root(), null, weight, 1); | 544 | + Result<TopologyVertex, TopologyEdge> result = DIJKSTRA.search(graph, cluster.root(), null, hopCountWeight, 1); |
516 | for (Map.Entry<TopologyVertex, Set<TopologyEdge>> entry : result.parents().entrySet()) { | 545 | for (Map.Entry<TopologyVertex, Set<TopologyEdge>> entry : result.parents().entrySet()) { |
517 | TopologyVertex vertex = entry.getKey(); | 546 | TopologyVertex vertex = entry.getKey(); |
518 | 547 | ||
... | @@ -577,23 +606,12 @@ public class DefaultTopology extends AbstractModel implements Topology { | ... | @@ -577,23 +606,12 @@ public class DefaultTopology extends AbstractModel implements Topology { |
577 | linksBuilder.build()); | 606 | linksBuilder.build()); |
578 | } | 607 | } |
579 | 608 | ||
580 | - // Link weight for measuring link cost as hop count with indirect links | 609 | + private GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch() { |
581 | - // being as expensive as traversing the entire graph to assume the worst. | 610 | + return defaultGraphPathSearch != null ? defaultGraphPathSearch : DIJKSTRA; |
582 | - private static class HopCountLinkWeight implements LinkWeight { | ||
583 | - private final int indirectLinkCost; | ||
584 | - | ||
585 | - HopCountLinkWeight(int indirectLinkCost) { | ||
586 | - this.indirectLinkCost = indirectLinkCost; | ||
587 | } | 611 | } |
588 | 612 | ||
589 | - @Override | 613 | + private LinkWeight linkWeight() { |
590 | - public double weight(TopologyEdge edge) { | 614 | + return defaultLinkWeight != null ? defaultLinkWeight : hopCountWeight; |
591 | - // To force preference to use direct paths first, make indirect | ||
592 | - // links as expensive as the linear vertex traversal. | ||
593 | - return edge.link().state() == | ||
594 | - ACTIVE ? (edge.link().type() == | ||
595 | - INDIRECT ? indirectLinkCost : 1) : -1; | ||
596 | - } | ||
597 | } | 615 | } |
598 | 616 | ||
599 | // Link weight for preventing traversal over indirect links. | 617 | // Link weight for preventing traversal over indirect links. | ... | ... |
... | @@ -38,6 +38,7 @@ import org.slf4j.Logger; | ... | @@ -38,6 +38,7 @@ import org.slf4j.Logger; |
38 | public final class BasicLinkOperator implements ConfigOperator { | 38 | public final class BasicLinkOperator implements ConfigOperator { |
39 | 39 | ||
40 | private static final long DEF_BANDWIDTH = -1L; | 40 | private static final long DEF_BANDWIDTH = -1L; |
41 | + private static final double DEF_METRIC = -1; | ||
41 | private static final Duration DEF_DURATION = Duration.ofNanos(-1L); | 42 | private static final Duration DEF_DURATION = Duration.ofNanos(-1L); |
42 | private static final Logger log = getLogger(BasicLinkOperator.class); | 43 | private static final Logger log = getLogger(BasicLinkOperator.class); |
43 | 44 | ||
... | @@ -77,6 +78,9 @@ public final class BasicLinkOperator implements ConfigOperator { | ... | @@ -77,6 +78,9 @@ public final class BasicLinkOperator implements ConfigOperator { |
77 | */ | 78 | */ |
78 | public static SparseAnnotations combine(BasicLinkConfig cfg, SparseAnnotations an) { | 79 | public static SparseAnnotations combine(BasicLinkConfig cfg, SparseAnnotations an) { |
79 | DefaultAnnotations.Builder b = DefaultAnnotations.builder(); | 80 | DefaultAnnotations.Builder b = DefaultAnnotations.builder(); |
81 | + if (cfg.metric() != DEF_METRIC) { | ||
82 | + b.set(AnnotationKeys.METRIC, String.valueOf(cfg.metric())); | ||
83 | + } | ||
80 | if (cfg.latency() != DEF_DURATION) { | 84 | if (cfg.latency() != DEF_DURATION) { |
81 | b.set(AnnotationKeys.LATENCY, cfg.latency().toString()); | 85 | b.set(AnnotationKeys.LATENCY, cfg.latency().toString()); |
82 | } | 86 | } | ... | ... |
... | @@ -15,44 +15,43 @@ | ... | @@ -15,44 +15,43 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.store.topology.impl; | 16 | package org.onosproject.store.topology.impl; |
17 | 17 | ||
18 | -import static com.google.common.base.Preconditions.checkArgument; | ||
19 | -import static org.onlab.util.Tools.isNullOrEmpty; | ||
20 | -import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED; | ||
21 | -import static org.slf4j.LoggerFactory.getLogger; | ||
22 | - | ||
23 | -import java.util.Collections; | ||
24 | -import java.util.Map; | ||
25 | -import java.util.List; | ||
26 | -import java.util.Set; | ||
27 | -import java.util.stream.Collectors; | ||
28 | - | ||
29 | import org.apache.felix.scr.annotations.Activate; | 18 | import org.apache.felix.scr.annotations.Activate; |
30 | import org.apache.felix.scr.annotations.Component; | 19 | import org.apache.felix.scr.annotations.Component; |
31 | import org.apache.felix.scr.annotations.Deactivate; | 20 | import org.apache.felix.scr.annotations.Deactivate; |
21 | +import org.apache.felix.scr.annotations.Modified; | ||
22 | +import org.apache.felix.scr.annotations.Property; | ||
32 | import org.apache.felix.scr.annotations.Reference; | 23 | import org.apache.felix.scr.annotations.Reference; |
33 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
34 | import org.apache.felix.scr.annotations.Service; | 25 | import org.apache.felix.scr.annotations.Service; |
26 | +import org.onlab.graph.GraphPathSearch; | ||
35 | import org.onlab.util.KryoNamespace; | 27 | import org.onlab.util.KryoNamespace; |
28 | +import org.onosproject.cfg.ComponentConfigService; | ||
36 | import org.onosproject.common.DefaultTopology; | 29 | import org.onosproject.common.DefaultTopology; |
37 | import org.onosproject.event.Event; | 30 | import org.onosproject.event.Event; |
38 | import org.onosproject.mastership.MastershipService; | 31 | import org.onosproject.mastership.MastershipService; |
39 | import org.onosproject.net.ConnectPoint; | 32 | import org.onosproject.net.ConnectPoint; |
40 | import org.onosproject.net.Device; | 33 | import org.onosproject.net.Device; |
41 | import org.onosproject.net.DeviceId; | 34 | import org.onosproject.net.DeviceId; |
35 | +import org.onosproject.net.DisjointPath; | ||
42 | import org.onosproject.net.Link; | 36 | import org.onosproject.net.Link; |
43 | import org.onosproject.net.Path; | 37 | import org.onosproject.net.Path; |
44 | -import org.onosproject.net.DisjointPath; | 38 | +import org.onosproject.net.device.DeviceService; |
45 | import org.onosproject.net.provider.ProviderId; | 39 | import org.onosproject.net.provider.ProviderId; |
46 | import org.onosproject.net.topology.ClusterId; | 40 | import org.onosproject.net.topology.ClusterId; |
47 | import org.onosproject.net.topology.DefaultGraphDescription; | 41 | import org.onosproject.net.topology.DefaultGraphDescription; |
42 | +import org.onosproject.net.topology.GeoDistanceLinkWeight; | ||
48 | import org.onosproject.net.topology.GraphDescription; | 43 | import org.onosproject.net.topology.GraphDescription; |
49 | import org.onosproject.net.topology.LinkWeight; | 44 | import org.onosproject.net.topology.LinkWeight; |
45 | +import org.onosproject.net.topology.MetricLinkWeight; | ||
46 | +import org.onosproject.net.topology.PathAdminService; | ||
50 | import org.onosproject.net.topology.Topology; | 47 | import org.onosproject.net.topology.Topology; |
51 | import org.onosproject.net.topology.TopologyCluster; | 48 | import org.onosproject.net.topology.TopologyCluster; |
49 | +import org.onosproject.net.topology.TopologyEdge; | ||
52 | import org.onosproject.net.topology.TopologyEvent; | 50 | import org.onosproject.net.topology.TopologyEvent; |
53 | import org.onosproject.net.topology.TopologyGraph; | 51 | import org.onosproject.net.topology.TopologyGraph; |
54 | import org.onosproject.net.topology.TopologyStore; | 52 | import org.onosproject.net.topology.TopologyStore; |
55 | import org.onosproject.net.topology.TopologyStoreDelegate; | 53 | import org.onosproject.net.topology.TopologyStoreDelegate; |
54 | +import org.onosproject.net.topology.TopologyVertex; | ||
56 | import org.onosproject.store.AbstractStore; | 55 | import org.onosproject.store.AbstractStore; |
57 | import org.onosproject.store.serializers.KryoNamespaces; | 56 | import org.onosproject.store.serializers.KryoNamespaces; |
58 | import org.onosproject.store.service.EventuallyConsistentMap; | 57 | import org.onosproject.store.service.EventuallyConsistentMap; |
... | @@ -60,8 +59,23 @@ import org.onosproject.store.service.EventuallyConsistentMapEvent; | ... | @@ -60,8 +59,23 @@ import org.onosproject.store.service.EventuallyConsistentMapEvent; |
60 | import org.onosproject.store.service.EventuallyConsistentMapListener; | 59 | import org.onosproject.store.service.EventuallyConsistentMapListener; |
61 | import org.onosproject.store.service.LogicalClockService; | 60 | import org.onosproject.store.service.LogicalClockService; |
62 | import org.onosproject.store.service.StorageService; | 61 | import org.onosproject.store.service.StorageService; |
62 | +import org.osgi.service.component.ComponentContext; | ||
63 | import org.slf4j.Logger; | 63 | import org.slf4j.Logger; |
64 | 64 | ||
65 | +import java.util.Collections; | ||
66 | +import java.util.Dictionary; | ||
67 | +import java.util.List; | ||
68 | +import java.util.Map; | ||
69 | +import java.util.Objects; | ||
70 | +import java.util.Set; | ||
71 | +import java.util.stream.Collectors; | ||
72 | + | ||
73 | +import static com.google.common.base.Preconditions.checkArgument; | ||
74 | +import static org.onlab.util.Tools.get; | ||
75 | +import static org.onlab.util.Tools.isNullOrEmpty; | ||
76 | +import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED; | ||
77 | +import static org.slf4j.LoggerFactory.getLogger; | ||
78 | + | ||
65 | /** | 79 | /** |
66 | * Manages inventory of topology snapshots using trivial in-memory | 80 | * Manages inventory of topology snapshots using trivial in-memory |
67 | * structures implementation. | 81 | * structures implementation. |
... | @@ -73,9 +87,12 @@ import org.slf4j.Logger; | ... | @@ -73,9 +87,12 @@ import org.slf4j.Logger; |
73 | @Service | 87 | @Service |
74 | public class DistributedTopologyStore | 88 | public class DistributedTopologyStore |
75 | extends AbstractStore<TopologyEvent, TopologyStoreDelegate> | 89 | extends AbstractStore<TopologyEvent, TopologyStoreDelegate> |
76 | - implements TopologyStore { | 90 | + implements TopologyStore, PathAdminService { |
77 | 91 | ||
78 | private final Logger log = getLogger(getClass()); | 92 | private final Logger log = getLogger(getClass()); |
93 | + | ||
94 | + private static final String FORMAT = "Settings: linkWeightFunction={}"; | ||
95 | + | ||
79 | private volatile DefaultTopology current = | 96 | private volatile DefaultTopology current = |
80 | new DefaultTopology(ProviderId.NONE, | 97 | new DefaultTopology(ProviderId.NONE, |
81 | new DefaultGraphDescription(0L, System.currentTimeMillis(), | 98 | new DefaultGraphDescription(0L, System.currentTimeMillis(), |
... | @@ -91,6 +108,21 @@ public class DistributedTopologyStore | ... | @@ -91,6 +108,21 @@ public class DistributedTopologyStore |
91 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 108 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
92 | protected MastershipService mastershipService; | 109 | protected MastershipService mastershipService; |
93 | 110 | ||
111 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
112 | + protected ComponentConfigService configService; | ||
113 | + | ||
114 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
115 | + protected DeviceService deviceService; | ||
116 | + | ||
117 | + private static final String HOP_COUNT = "hopCount"; | ||
118 | + private static final String LINK_METRIC = "linkMetric"; | ||
119 | + private static final String GEO_DISTANCE = "geoDistance"; | ||
120 | + | ||
121 | + private static final String DEFAULT_LINK_WEIGHT_FUNCTION = "hopCount"; | ||
122 | + @Property(name = "linkWeightFunction", value = DEFAULT_LINK_WEIGHT_FUNCTION, | ||
123 | + label = "Default link-weight function: hopCount, linkMetric, geoDistance") | ||
124 | + private String linkWeightFunction = DEFAULT_LINK_WEIGHT_FUNCTION; | ||
125 | + | ||
94 | // Cluster root to broadcast points bindings to allow convergence to | 126 | // Cluster root to broadcast points bindings to allow convergence to |
95 | // a shared broadcast tree; node that is the master of the cluster root | 127 | // a shared broadcast tree; node that is the master of the cluster root |
96 | // is the primary. | 128 | // is the primary. |
... | @@ -100,7 +132,8 @@ public class DistributedTopologyStore | ... | @@ -100,7 +132,8 @@ public class DistributedTopologyStore |
100 | new InternalBroadcastPointListener(); | 132 | new InternalBroadcastPointListener(); |
101 | 133 | ||
102 | @Activate | 134 | @Activate |
103 | - public void activate() { | 135 | + protected void activate() { |
136 | + configService.registerProperties(getClass()); | ||
104 | KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder() | 137 | KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder() |
105 | .register(KryoNamespaces.API); | 138 | .register(KryoNamespaces.API); |
106 | 139 | ||
... | @@ -114,12 +147,30 @@ public class DistributedTopologyStore | ... | @@ -114,12 +147,30 @@ public class DistributedTopologyStore |
114 | } | 147 | } |
115 | 148 | ||
116 | @Deactivate | 149 | @Deactivate |
117 | - public void deactivate() { | 150 | + protected void deactivate() { |
151 | + configService.unregisterProperties(getClass(), false); | ||
118 | broadcastPoints.removeListener(listener); | 152 | broadcastPoints.removeListener(listener); |
119 | broadcastPoints.destroy(); | 153 | broadcastPoints.destroy(); |
120 | log.info("Stopped"); | 154 | log.info("Stopped"); |
121 | } | 155 | } |
122 | 156 | ||
157 | + @Modified | ||
158 | + protected void modified(ComponentContext context) { | ||
159 | + Dictionary<?, ?> properties = context.getProperties(); | ||
160 | + | ||
161 | + String newLinkWeightFunction = get(properties, "linkWeightFunction"); | ||
162 | + if (newLinkWeightFunction != null && | ||
163 | + !Objects.equals(newLinkWeightFunction, linkWeightFunction)) { | ||
164 | + linkWeightFunction = newLinkWeightFunction; | ||
165 | + LinkWeight weight = linkWeightFunction.equals(LINK_METRIC) ? | ||
166 | + new MetricLinkWeight() : | ||
167 | + linkWeightFunction.equals(GEO_DISTANCE) ? | ||
168 | + new GeoDistanceLinkWeight(deviceService) : null; | ||
169 | + setDefaultLinkWeight(weight); | ||
170 | + } | ||
171 | + log.info(FORMAT, linkWeightFunction); | ||
172 | + } | ||
173 | + | ||
123 | @Override | 174 | @Override |
124 | public Topology currentTopology() { | 175 | public Topology currentTopology() { |
125 | return current; | 176 | return current; |
... | @@ -263,6 +314,16 @@ public class DistributedTopologyStore | ... | @@ -263,6 +314,16 @@ public class DistributedTopologyStore |
263 | return (DefaultTopology) topology; | 314 | return (DefaultTopology) topology; |
264 | } | 315 | } |
265 | 316 | ||
317 | + @Override | ||
318 | + public void setDefaultLinkWeight(LinkWeight linkWeight) { | ||
319 | + DefaultTopology.setDefaultLinkWeight(linkWeight); | ||
320 | + } | ||
321 | + | ||
322 | + @Override | ||
323 | + public void setDefaultGraphPathSearch(GraphPathSearch<TopologyVertex, TopologyEdge> graphPathSearch) { | ||
324 | + DefaultTopology.setDefaultGraphPathSearch(graphPathSearch); | ||
325 | + } | ||
326 | + | ||
266 | private class InternalBroadcastPointListener | 327 | private class InternalBroadcastPointListener |
267 | implements EventuallyConsistentMapListener<DeviceId, Set<ConnectPoint>> { | 328 | implements EventuallyConsistentMapListener<DeviceId, Set<ConnectPoint>> { |
268 | @Override | 329 | @Override | ... | ... |
... | @@ -168,7 +168,7 @@ public class NullProviders { | ... | @@ -168,7 +168,7 @@ public class NullProviders { |
168 | 168 | ||
169 | 169 | ||
170 | @Activate | 170 | @Activate |
171 | - public void activate(ComponentContext context) { | 171 | + public void activate() { |
172 | cfgService.registerProperties(getClass()); | 172 | cfgService.registerProperties(getClass()); |
173 | 173 | ||
174 | deviceProviderService = deviceProviderRegistry.register(deviceProvider); | 174 | deviceProviderService = deviceProviderRegistry.register(deviceProvider); |
... | @@ -180,7 +180,7 @@ public class NullProviders { | ... | @@ -180,7 +180,7 @@ public class NullProviders { |
180 | } | 180 | } |
181 | 181 | ||
182 | @Deactivate | 182 | @Deactivate |
183 | - public void deactivate(ComponentContext context) { | 183 | + public void deactivate() { |
184 | cfgService.unregisterProperties(getClass(), false); | 184 | cfgService.unregisterProperties(getClass(), false); |
185 | tearDown(); | 185 | tearDown(); |
186 | 186 | ... | ... |
1 | +/* | ||
2 | + * Copyright 2014-2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onlab.util; | ||
18 | + | ||
19 | +import com.google.common.base.MoreObjects; | ||
20 | + | ||
21 | +/** | ||
22 | + * Geo location specified in terms of longitude and latitude. | ||
23 | + */ | ||
24 | +public class GeoLocation { | ||
25 | + | ||
26 | + public static final double EARTH_RADIUS_KM = 6378.1370D; | ||
27 | + | ||
28 | + private final double latitude; | ||
29 | + private final double longitude; | ||
30 | + | ||
31 | + /** | ||
32 | + * Creates a new location using the specified coordinates. | ||
33 | + * | ||
34 | + * @param latitude latitude line | ||
35 | + * @param longitude longitude line | ||
36 | + */ | ||
37 | + public GeoLocation(double latitude, double longitude) { | ||
38 | + this.latitude = latitude; | ||
39 | + this.longitude = longitude; | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * Returns the latitude of this location. | ||
44 | + * | ||
45 | + * @return latitude | ||
46 | + */ | ||
47 | + public double latitude() { | ||
48 | + return latitude; | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Returns the longitude of this location. | ||
53 | + * | ||
54 | + * @return longitude | ||
55 | + */ | ||
56 | + public double longitude() { | ||
57 | + return longitude; | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * Returns the distance in kilometers, between this location and another. | ||
62 | + * | ||
63 | + * @param other other geo location | ||
64 | + * @return distance in kilometers | ||
65 | + */ | ||
66 | + public double kilometersTo(GeoLocation other) { | ||
67 | + double hereLat = Math.toRadians(latitude); | ||
68 | + double hereLon = Math.toRadians(longitude); | ||
69 | + double thereLat = Math.toRadians(other.latitude); | ||
70 | + double thereLon = Math.toRadians(other.longitude); | ||
71 | + | ||
72 | + double cos = Math.sin(hereLat) * Math.sin(thereLat) + | ||
73 | + Math.cos(hereLat) * Math.cos(thereLat) * Math.cos(hereLon - thereLon); | ||
74 | + return Math.acos(cos) * EARTH_RADIUS_KM; | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public String toString() { | ||
79 | + return MoreObjects.toStringHelper(this) | ||
80 | + .add("latitude", latitude) | ||
81 | + .add("longitude", longitude) | ||
82 | + .toString(); | ||
83 | + } | ||
84 | + | ||
85 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onlab.util; | ||
18 | + | ||
19 | +import org.junit.Test; | ||
20 | + | ||
21 | +import static org.junit.Assert.assertEquals; | ||
22 | + | ||
23 | +/** | ||
24 | + * Test suite of the geo location. | ||
25 | + */ | ||
26 | +public class GeoLocationTest { | ||
27 | + | ||
28 | + @Test | ||
29 | + public void basics() { | ||
30 | + GeoLocation nLoc = new GeoLocation(40.7127, -74.0059); | ||
31 | + GeoLocation wLoc = new GeoLocation(38.9047, -77.0164); | ||
32 | + | ||
33 | + assertEquals("incorrect latitude", 40.7127, nLoc.latitude(), 0.0001); | ||
34 | + assertEquals("incorrect longitude", -74.00598, nLoc.longitude(), 0.0001); | ||
35 | + assertEquals("incorrect distance", 326.74, nLoc.kilometersTo(wLoc), 0.01); | ||
36 | + } | ||
37 | + | ||
38 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment