Clean up handling of lat/long geo-coordinates.
Change-Id: I64fca56c7deb9a8baa6c68558365ec2a8c38168c
Showing
6 changed files
with
144 additions
and
28 deletions
... | @@ -30,12 +30,13 @@ public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { | ... | @@ -30,12 +30,13 @@ public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { |
30 | protected static final String RACK_ADDRESS = "rackAddress"; | 30 | protected static final String RACK_ADDRESS = "rackAddress"; |
31 | protected static final String OWNER = "owner"; | 31 | protected static final String OWNER = "owner"; |
32 | 32 | ||
33 | - protected static final double DEFAULT_COORD = -1.0; | 33 | + protected static final double ZERO_THRESHOLD = Double.MIN_VALUE * 2.0; |
34 | + private static final double DEFAULT_COORD = 0.0; | ||
34 | 35 | ||
35 | /** | 36 | /** |
36 | * Returns friendly label for the element. | 37 | * Returns friendly label for the element. |
37 | * | 38 | * |
38 | - * @return friendly label or element id itself if not set | 39 | + * @return friendly label or element identifier itself if not set |
39 | */ | 40 | */ |
40 | public String name() { | 41 | public String name() { |
41 | return get(NAME, subject.toString()); | 42 | return get(NAME, subject.toString()); |
... | @@ -51,10 +52,25 @@ public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { | ... | @@ -51,10 +52,25 @@ public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { |
51 | return (BasicElementConfig) setOrClear(NAME, name); | 52 | return (BasicElementConfig) setOrClear(NAME, name); |
52 | } | 53 | } |
53 | 54 | ||
55 | + private static boolean doubleIsZero(double value) { | ||
56 | + return value >= -ZERO_THRESHOLD && value <= ZERO_THRESHOLD; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Returns true if the geographical coordinates (latitude and longitude) | ||
61 | + * are set on this element. | ||
62 | + * | ||
63 | + * @return true if geo-coordinates are set | ||
64 | + */ | ||
65 | + public boolean geoCoordsSet() { | ||
66 | + return !doubleIsZero(latitude()) || !doubleIsZero(longitude()); | ||
67 | + } | ||
68 | + | ||
54 | /** | 69 | /** |
55 | * Returns element latitude. | 70 | * Returns element latitude. |
56 | * | 71 | * |
57 | - * @return element latitude; -1 if not set | 72 | + * @return element latitude; 0.0 if (possibly) not set |
73 | + * @see #geoCoordsSet() | ||
58 | */ | 74 | */ |
59 | public double latitude() { | 75 | public double latitude() { |
60 | return get(LATITUDE, DEFAULT_COORD); | 76 | return get(LATITUDE, DEFAULT_COORD); |
... | @@ -71,9 +87,10 @@ public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { | ... | @@ -71,9 +87,10 @@ public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> { |
71 | } | 87 | } |
72 | 88 | ||
73 | /** | 89 | /** |
74 | - * Returns element latitude. | 90 | + * Returns element longitude. |
75 | * | 91 | * |
76 | - * @return element latitude; -1 if not set | 92 | + * @return element longitude; 0 if (possibly) not set |
93 | + * @see #geoCoordsSet() | ||
77 | */ | 94 | */ |
78 | public double longitude() { | 95 | public double longitude() { |
79 | return get(LONGITUDE, DEFAULT_COORD); | 96 | return get(LONGITUDE, DEFAULT_COORD); | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present 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.config.basics; | ||
18 | + | ||
19 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | +import org.junit.Before; | ||
21 | +import org.junit.Test; | ||
22 | + | ||
23 | +import static org.junit.Assert.assertEquals; | ||
24 | +import static org.junit.Assert.assertFalse; | ||
25 | +import static org.junit.Assert.assertTrue; | ||
26 | +import static org.onosproject.net.config.basics.BasicElementConfig.ZERO_THRESHOLD; | ||
27 | + | ||
28 | +/** | ||
29 | + * Unit tests for {@link BasicElementConfig}. | ||
30 | + */ | ||
31 | +public class BasicElementConfigTest { | ||
32 | + | ||
33 | + private static final ObjectMapper MAPPER = new ObjectMapper(); | ||
34 | + | ||
35 | + private static final String E1 = "e1"; | ||
36 | + | ||
37 | + // concrete subclass of abstract class we are testing | ||
38 | + private static class ElmCfg extends BasicElementConfig<String> { | ||
39 | + ElmCfg() { | ||
40 | + object = MAPPER.createObjectNode(); | ||
41 | + } | ||
42 | + | ||
43 | + @Override | ||
44 | + public String toString() { | ||
45 | + return object.toString(); | ||
46 | + } | ||
47 | + } | ||
48 | + | ||
49 | + private static void print(String fmt, Object... args) { | ||
50 | + System.out.println(String.format(fmt, args)); | ||
51 | + } | ||
52 | + | ||
53 | + private static void print(Object o) { | ||
54 | + print("%s", o); | ||
55 | + } | ||
56 | + | ||
57 | + private BasicElementConfig<?> cfg; | ||
58 | + | ||
59 | + @Before | ||
60 | + public void setUp() { | ||
61 | + cfg = new ElmCfg().name(E1); | ||
62 | + } | ||
63 | + | ||
64 | + @Test | ||
65 | + public void basicNoGeo() { | ||
66 | + print(cfg); | ||
67 | + assertFalse("geo set?", cfg.geoCoordsSet()); | ||
68 | + assertEquals("lat", 0.0, cfg.latitude(), ZERO_THRESHOLD); | ||
69 | + assertEquals("lon", 0.0, cfg.longitude(), ZERO_THRESHOLD); | ||
70 | + } | ||
71 | + | ||
72 | + @Test | ||
73 | + public void geoLatitudeOnly() { | ||
74 | + cfg.latitude(0.1); | ||
75 | + print(cfg); | ||
76 | + assertTrue("geo NOT set", cfg.geoCoordsSet()); | ||
77 | + assertEquals("lat", 0.1, cfg.latitude(), ZERO_THRESHOLD); | ||
78 | + assertEquals("lon", 0.0, cfg.longitude(), ZERO_THRESHOLD); | ||
79 | + } | ||
80 | + | ||
81 | + @Test | ||
82 | + public void geoLongitudeOnly() { | ||
83 | + cfg.longitude(-0.1); | ||
84 | + print(cfg); | ||
85 | + assertTrue("geo NOT set", cfg.geoCoordsSet()); | ||
86 | + assertEquals("lat", 0.0, cfg.latitude(), ZERO_THRESHOLD); | ||
87 | + assertEquals("lon", -0.1, cfg.longitude(), ZERO_THRESHOLD); | ||
88 | + } | ||
89 | + | ||
90 | + @Test | ||
91 | + public void geoLatLong() { | ||
92 | + cfg.latitude(3.1415).longitude(2.71828); | ||
93 | + print(cfg); | ||
94 | + assertTrue("geo NOT set", cfg.geoCoordsSet()); | ||
95 | + assertEquals("lat", 3.1415, cfg.latitude(), ZERO_THRESHOLD); | ||
96 | + assertEquals("lon", 2.71828, cfg.longitude(), ZERO_THRESHOLD); | ||
97 | + } | ||
98 | +} |
... | @@ -34,8 +34,6 @@ import java.util.Set; | ... | @@ -34,8 +34,6 @@ import java.util.Set; |
34 | */ | 34 | */ |
35 | public final class BasicHostOperator implements ConfigOperator { | 35 | public final class BasicHostOperator implements ConfigOperator { |
36 | 36 | ||
37 | - protected static final double DEFAULT_COORD = -1.0; | ||
38 | - | ||
39 | private BasicHostOperator() { | 37 | private BasicHostOperator() { |
40 | } | 38 | } |
41 | 39 | ||
... | @@ -81,10 +79,8 @@ public final class BasicHostOperator implements ConfigOperator { | ... | @@ -81,10 +79,8 @@ public final class BasicHostOperator implements ConfigOperator { |
81 | if (cfg.name() != null) { | 79 | if (cfg.name() != null) { |
82 | newBuilder.set(AnnotationKeys.NAME, cfg.name()); | 80 | newBuilder.set(AnnotationKeys.NAME, cfg.name()); |
83 | } | 81 | } |
84 | - if (cfg.latitude() != DEFAULT_COORD) { | 82 | + if (cfg.geoCoordsSet()) { |
85 | newBuilder.set(AnnotationKeys.LATITUDE, Double.toString(cfg.latitude())); | 83 | newBuilder.set(AnnotationKeys.LATITUDE, Double.toString(cfg.latitude())); |
86 | - } | ||
87 | - if (cfg.longitude() != DEFAULT_COORD) { | ||
88 | newBuilder.set(AnnotationKeys.LONGITUDE, Double.toString(cfg.longitude())); | 84 | newBuilder.set(AnnotationKeys.LONGITUDE, Double.toString(cfg.longitude())); |
89 | } | 85 | } |
90 | if (cfg.rackAddress() != null) { | 86 | if (cfg.rackAddress() != null) { | ... | ... |
... | @@ -54,18 +54,20 @@ public class BasicHostOperatorTest { | ... | @@ -54,18 +54,20 @@ public class BasicHostOperatorTest { |
54 | private static final BasicHostConfig BHC = new BasicHostConfig(); | 54 | private static final BasicHostConfig BHC = new BasicHostConfig(); |
55 | private static final String NAME = "testhost"; | 55 | private static final String NAME = "testhost"; |
56 | private static final double LAT = 40.96; | 56 | private static final double LAT = 40.96; |
57 | + private static final double LON = 0.0; | ||
57 | 58 | ||
58 | @Before | 59 | @Before |
59 | public void setUp() { | 60 | public void setUp() { |
60 | BHC.init(ID, "test", JsonNodeFactory.instance.objectNode(), mapper, delegate); | 61 | BHC.init(ID, "test", JsonNodeFactory.instance.objectNode(), mapper, delegate); |
61 | BHC.name(NAME).latitude(40.96); | 62 | BHC.name(NAME).latitude(40.96); |
63 | + // if you set lat or long, the other becomes valid as 0.0 (not null) | ||
62 | } | 64 | } |
63 | 65 | ||
64 | @Test | 66 | @Test |
65 | public void testDescOps() { | 67 | public void testDescOps() { |
66 | HostDescription desc = BasicHostOperator.combine(BHC, HOST); | 68 | HostDescription desc = BasicHostOperator.combine(BHC, HOST); |
67 | assertEquals(NAME, desc.annotations().value(AnnotationKeys.NAME)); | 69 | assertEquals(NAME, desc.annotations().value(AnnotationKeys.NAME)); |
68 | - assertEquals(null, desc.annotations().value(AnnotationKeys.LONGITUDE)); | 70 | + assertEquals(String.valueOf(LON), desc.annotations().value(AnnotationKeys.LONGITUDE)); |
69 | assertEquals(String.valueOf(LAT), desc.annotations().value(AnnotationKeys.LATITUDE)); | 71 | assertEquals(String.valueOf(LAT), desc.annotations().value(AnnotationKeys.LATITUDE)); |
70 | } | 72 | } |
71 | } | 73 | } | ... | ... |
... | @@ -7,12 +7,15 @@ onos ${host} null-simulation stop custom | ... | @@ -7,12 +7,15 @@ onos ${host} null-simulation stop custom |
7 | onos ${host} wipe-out please | 7 | onos ${host} wipe-out please |
8 | onos ${host} null-simulation start custom | 8 | onos ${host} null-simulation start custom |
9 | 9 | ||
10 | +# null-create-device <type> <name> <#ports> <latitude> <longitude> | ||
11 | +# null-create-link <type> <src> <dst> | ||
12 | + | ||
10 | onos ${host} <<-EOF | 13 | onos ${host} <<-EOF |
11 | 14 | ||
12 | -null-create-device switch s1 10 0 0 | 15 | +null-create-device switch s1-Bristol 10 51.4500 -2.5833 |
13 | -null-create-device switch s2 10 0 0 | 16 | +null-create-device switch s2-London 10 51.5072 -0.1275 |
14 | -null-create-device switch s3 10 0 0 | 17 | +null-create-device switch s3-Dover 10 51.1295 1.3089 |
15 | -null-create-device switch s4 10 0 0 | 18 | +null-create-device switch s4-Brighton 10 50.8429 -0.1313 |
16 | null-create-device switch s5 10 0 0 | 19 | null-create-device switch s5 10 0 0 |
17 | null-create-device switch s6 10 0 0 | 20 | null-create-device switch s6 10 0 0 |
18 | null-create-device switch s7 10 0 0 | 21 | null-create-device switch s7 10 0 0 |
... | @@ -20,11 +23,11 @@ null-create-device switch s8 10 0 0 | ... | @@ -20,11 +23,11 @@ null-create-device switch s8 10 0 0 |
20 | null-create-device switch s9 10 0 0 | 23 | null-create-device switch s9 10 0 0 |
21 | # null-create-device switch s10 10 0 0 | 24 | # null-create-device switch s10 10 0 0 |
22 | 25 | ||
23 | -null-create-link direct s1 s2 | 26 | +null-create-link direct s1-Bristol s2-London |
24 | -null-create-link direct s2 s3 | 27 | +null-create-link direct s2-London s3-Dover |
25 | -null-create-link direct s2 s4 | 28 | +null-create-link direct s2-London s4-Brighton |
26 | -null-create-link direct s3 s4 | 29 | +null-create-link direct s3-Dover s4-Brighton |
27 | -null-create-link direct s3 s5 | 30 | +null-create-link direct s3-Dover s5 |
28 | null-create-link direct s6 s5 | 31 | null-create-link direct s6 s5 |
29 | null-create-link direct s6 s8 | 32 | null-create-link direct s6 s8 |
30 | null-create-link direct s7 s9 | 33 | null-create-link direct s7 s9 | ... | ... |
... | @@ -31,7 +31,6 @@ import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint; | ... | @@ -31,7 +31,6 @@ import org.onosproject.incubator.net.tunnel.OpticalTunnelEndPoint; |
31 | import org.onosproject.incubator.net.tunnel.Tunnel; | 31 | import org.onosproject.incubator.net.tunnel.Tunnel; |
32 | import org.onosproject.incubator.net.tunnel.TunnelService; | 32 | import org.onosproject.incubator.net.tunnel.TunnelService; |
33 | import org.onosproject.mastership.MastershipService; | 33 | import org.onosproject.mastership.MastershipService; |
34 | -import org.onosproject.net.ElementId; | ||
35 | import org.onosproject.net.Annotated; | 34 | import org.onosproject.net.Annotated; |
36 | import org.onosproject.net.AnnotationKeys; | 35 | import org.onosproject.net.AnnotationKeys; |
37 | import org.onosproject.net.Annotations; | 36 | import org.onosproject.net.Annotations; |
... | @@ -40,6 +39,7 @@ import org.onosproject.net.DefaultEdgeLink; | ... | @@ -40,6 +39,7 @@ import org.onosproject.net.DefaultEdgeLink; |
40 | import org.onosproject.net.Device; | 39 | import org.onosproject.net.Device; |
41 | import org.onosproject.net.DeviceId; | 40 | import org.onosproject.net.DeviceId; |
42 | import org.onosproject.net.EdgeLink; | 41 | import org.onosproject.net.EdgeLink; |
42 | +import org.onosproject.net.ElementId; | ||
43 | import org.onosproject.net.Host; | 43 | import org.onosproject.net.Host; |
44 | import org.onosproject.net.HostId; | 44 | import org.onosproject.net.HostId; |
45 | import org.onosproject.net.HostLocation; | 45 | import org.onosproject.net.HostLocation; |
... | @@ -77,8 +77,8 @@ import java.util.HashSet; | ... | @@ -77,8 +77,8 @@ import java.util.HashSet; |
77 | import java.util.Iterator; | 77 | import java.util.Iterator; |
78 | import java.util.List; | 78 | import java.util.List; |
79 | import java.util.Map; | 79 | import java.util.Map; |
80 | -import java.util.Set; | ||
81 | import java.util.Optional; | 80 | import java.util.Optional; |
81 | +import java.util.Set; | ||
82 | import java.util.concurrent.ConcurrentHashMap; | 82 | import java.util.concurrent.ConcurrentHashMap; |
83 | 83 | ||
84 | import static com.google.common.base.Preconditions.checkNotNull; | 84 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -94,6 +94,8 @@ import static org.onosproject.ui.topo.TopoUtils.compactLinkString; | ... | @@ -94,6 +94,8 @@ import static org.onosproject.ui.topo.TopoUtils.compactLinkString; |
94 | */ | 94 | */ |
95 | public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | 95 | public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
96 | 96 | ||
97 | + private static final String NO_GEO_VALUE = "0.0"; | ||
98 | + | ||
97 | // default to an "add" event... | 99 | // default to an "add" event... |
98 | private static final DefaultHashMap<ClusterEvent.Type, String> CLUSTER_EVENT = | 100 | private static final DefaultHashMap<ClusterEvent.Type, String> CLUSTER_EVENT = |
99 | new DefaultHashMap<>("addInstance"); | 101 | new DefaultHashMap<>("addInstance"); |
... | @@ -361,10 +363,10 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -361,10 +363,10 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
361 | 363 | ||
362 | String slng = annotations.value(AnnotationKeys.LONGITUDE); | 364 | String slng = annotations.value(AnnotationKeys.LONGITUDE); |
363 | String slat = annotations.value(AnnotationKeys.LATITUDE); | 365 | String slat = annotations.value(AnnotationKeys.LATITUDE); |
364 | - boolean haveLng = slng != null && !slng.isEmpty(); | 366 | + boolean validLng = slng != null && !slng.equals(NO_GEO_VALUE); |
365 | - boolean haveLat = slat != null && !slat.isEmpty(); | 367 | + boolean validLat = slat != null && !slat.equals(NO_GEO_VALUE); |
368 | + if (validLat && validLng) { | ||
366 | try { | 369 | try { |
367 | - if (haveLng && haveLat) { | ||
368 | double lng = Double.parseDouble(slng); | 370 | double lng = Double.parseDouble(slng); |
369 | double lat = Double.parseDouble(slat); | 371 | double lat = Double.parseDouble(slat); |
370 | ObjectNode loc = objectNode() | 372 | ObjectNode loc = objectNode() |
... | @@ -372,13 +374,11 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -372,13 +374,11 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
372 | .put("lng", lng) | 374 | .put("lng", lng) |
373 | .put("lat", lat); | 375 | .put("lat", lat); |
374 | payload.set("location", loc); | 376 | payload.set("location", loc); |
375 | - } else { | ||
376 | - log.trace("missing Lng/Lat: lng={}, lat={}", slng, slat); | ||
377 | - } | ||
378 | } catch (NumberFormatException e) { | 377 | } catch (NumberFormatException e) { |
379 | log.warn("Invalid geo data: longitude={}, latitude={}", slng, slat); | 378 | log.warn("Invalid geo data: longitude={}, latitude={}", slng, slat); |
380 | } | 379 | } |
381 | } | 380 | } |
381 | + } | ||
382 | 382 | ||
383 | // Updates meta UI information for the specified object. | 383 | // Updates meta UI information for the specified object. |
384 | protected void updateMetaUi(ObjectNode payload) { | 384 | protected void updateMetaUi(ObjectNode payload) { | ... | ... |
-
Please register or login to post a comment