Thomas Vachuska

Added link types of TUNNEL and OPTICAL.

Fixed the optical config json file.
Fixed treatment of links added by ancillary providers.
Added a trap for topology provider errors.
Added CLI to recompute topology.
...@@ -284,7 +284,7 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro ...@@ -284,7 +284,7 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro
284 DefaultLinkDescription linkDescription = 284 DefaultLinkDescription linkDescription =
285 new DefaultLinkDescription(srcPoint, 285 new DefaultLinkDescription(srcPoint,
286 snkPoint, 286 snkPoint,
287 - Link.Type.DIRECT, 287 + Link.Type.OPTICAL,
288 extendedAttributes); 288 extendedAttributes);
289 289
290 linkProviderService.linkDetected(linkDescription); 290 linkProviderService.linkDetected(linkDescription);
...@@ -315,7 +315,7 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro ...@@ -315,7 +315,7 @@ public class OpticalConfigProvider extends AbstractProvider implements DevicePro
315 DefaultLinkDescription linkDescription = 315 DefaultLinkDescription linkDescription =
316 new DefaultLinkDescription(srcPoint, 316 new DefaultLinkDescription(srcPoint,
317 snkPoint, 317 snkPoint,
318 - Link.Type.DIRECT, 318 + Link.Type.OPTICAL,
319 extendedAttributes); 319 extendedAttributes);
320 320
321 linkProviderService.linkDetected(linkDescription); 321 linkProviderService.linkDetected(linkDescription);
......
1 { 1 {
2 - "opticalSwitches": [ 2 + "opticalSwitches": [
3 { 3 {
4 "allowed": true, 4 "allowed": true,
5 "latitude": 37.6, 5 "latitude": 37.6,
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
12 "type": "Roadm" 12 "type": "Roadm"
13 }, 13 },
14 14
15 - { 15 + {
16 "allowed": true, 16 "allowed": true,
17 "latitude": 37.3, 17 "latitude": 37.3,
18 "longitude": 121.9, 18 "longitude": 121.9,
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
22 "numRegen": 0 22 "numRegen": 0
23 }, 23 },
24 "type": "Roadm" 24 "type": "Roadm"
25 - }, 25 + },
26 26
27 - { 27 + {
28 "allowed": true, 28 "allowed": true,
29 "latitude": 33.9, 29 "latitude": 33.9,
30 "longitude": 118.4, 30 "longitude": 118.4,
...@@ -34,10 +34,10 @@ ...@@ -34,10 +34,10 @@
34 "numRegen": 2 34 "numRegen": 2
35 }, 35 },
36 "type": "Roadm" 36 "type": "Roadm"
37 - } 37 + }
38 ], 38 ],
39 39
40 - "opticalLinks": [ 40 + "opticalLinks": [
41 { 41 {
42 "allowed": true, 42 "allowed": true,
43 "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01", 43 "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
...@@ -51,10 +51,38 @@ ...@@ -51,10 +51,38 @@
51 "port2": 30 51 "port2": 30
52 }, 52 },
53 "type": "wdmLink" 53 "type": "wdmLink"
54 - }, 54 + },
55 - 55 + {
56 - { 56 + "allowed": true,
57 - "allowed": true, 57 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
58 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01",
59 + "params": {
60 + "distKms": 1000,
61 + "nodeName1": "ROADM3",
62 + "nodeName2": "ROADM1",
63 + "numWaves": 80,
64 + "port1": 30,
65 + "port2": 10
66 + },
67 + "type": "wdmLink"
68 + },
69 +
70 + {
71 + "allowed": true,
72 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
73 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03",
74 + "params": {
75 + "distKms": 2000,
76 + "nodeName1": "ROADM2",
77 + "nodeName2": "ROADM3",
78 + "numWaves": 80,
79 + "port1": 20,
80 + "port2": 31
81 + },
82 + "type": "wdmLink"
83 + },
84 + {
85 + "allowed": true,
58 "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03", 86 "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
59 "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02", 87 "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02",
60 "params": { 88 "params": {
...@@ -66,10 +94,9 @@ ...@@ -66,10 +94,9 @@
66 "port2": 20 94 "port2": 20
67 }, 95 },
68 "type": "wdmLink" 96 "type": "wdmLink"
69 - }, 97 + },
70 98
71 - 99 + {
72 - {
73 "allowed": true, 100 "allowed": true,
74 "nodeDpid1": "00:00:ff:ff:ff:ff:00:01", 101 "nodeDpid1": "00:00:ff:ff:ff:ff:00:01",
75 "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01", 102 "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01",
...@@ -82,8 +109,21 @@ ...@@ -82,8 +109,21 @@
82 }, 109 },
83 "type": "pktOptLink" 110 "type": "pktOptLink"
84 }, 111 },
112 + {
113 + "allowed": true,
114 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
115 + "nodeDpid2": "00:00:ff:ff:ff:ff:00:01",
116 + "params": {
117 + "nodeName1": "ROADM1",
118 + "nodeName2": "ROUTER1",
119 + "bandWidth": 100000,
120 + "port1": 11,
121 + "port2": 10
122 + },
123 + "type": "pktOptLink"
124 + },
85 125
86 - { 126 + {
87 "allowed": true, 127 "allowed": true,
88 "nodeDpid1": "00:00:ff:ff:ff:ff:00:02", 128 "nodeDpid1": "00:00:ff:ff:ff:ff:00:02",
89 "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02", 129 "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02",
...@@ -95,7 +135,20 @@ ...@@ -95,7 +135,20 @@
95 "port2": 21 135 "port2": 21
96 }, 136 },
97 "type": "pktOptLink" 137 "type": "pktOptLink"
98 - } 138 + },
139 + {
140 + "allowed": true,
141 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
142 + "nodeDpid2": "00:00:ff:ff:ff:ff:00:02",
143 + "params": {
144 + "nodeName1": "ROADM2",
145 + "nodeName2": "ROUTER2",
146 + "bandWidth": 100000,
147 + "port1": 21,
148 + "port2": 10
149 + },
150 + "type": "pktOptLink"
151 + }
99 152
100 ] 153 ]
101 } 154 }
......
...@@ -20,8 +20,10 @@ package org.onlab.onos.cli.net; ...@@ -20,8 +20,10 @@ package org.onlab.onos.cli.net;
20 20
21 import com.fasterxml.jackson.databind.ObjectMapper; 21 import com.fasterxml.jackson.databind.ObjectMapper;
22 import org.apache.karaf.shell.commands.Command; 22 import org.apache.karaf.shell.commands.Command;
23 +import org.apache.karaf.shell.commands.Option;
23 import org.onlab.onos.cli.AbstractShellCommand; 24 import org.onlab.onos.cli.AbstractShellCommand;
24 import org.onlab.onos.net.topology.Topology; 25 import org.onlab.onos.net.topology.Topology;
26 +import org.onlab.onos.net.topology.TopologyProvider;
25 import org.onlab.onos.net.topology.TopologyService; 27 import org.onlab.onos.net.topology.TopologyService;
26 28
27 /** 29 /**
...@@ -35,6 +37,10 @@ public class TopologyCommand extends AbstractShellCommand { ...@@ -35,6 +37,10 @@ public class TopologyCommand extends AbstractShellCommand {
35 private static final String FMT = 37 private static final String FMT =
36 "time=%s, devices=%d, links=%d, clusters=%d, paths=%d"; 38 "time=%s, devices=%d, links=%d, clusters=%d, paths=%d";
37 39
40 + @Option(name = "-r", aliases = "--recompute", description = "Trigger topology re-computation",
41 + required = false, multiValued = false)
42 + private boolean recompute = false;
43 +
38 protected TopologyService service; 44 protected TopologyService service;
39 protected Topology topology; 45 protected Topology topology;
40 46
...@@ -49,7 +55,10 @@ public class TopologyCommand extends AbstractShellCommand { ...@@ -49,7 +55,10 @@ public class TopologyCommand extends AbstractShellCommand {
49 @Override 55 @Override
50 protected void execute() { 56 protected void execute() {
51 init(); 57 init();
52 - if (outputJson()) { 58 + if (recompute) {
59 + get(TopologyProvider.class).triggerRecompute();
60 +
61 + } else if (outputJson()) {
53 print("%s", new ObjectMapper().createObjectNode() 62 print("%s", new ObjectMapper().createObjectNode()
54 .put("time", topology.time()) 63 .put("time", topology.time())
55 .put("deviceCount", topology.deviceCount()) 64 .put("deviceCount", topology.deviceCount())
......
...@@ -25,7 +25,18 @@ public interface Link extends Annotated, Provided, NetworkResource { ...@@ -25,7 +25,18 @@ public interface Link extends Annotated, Provided, NetworkResource {
25 /** 25 /**
26 * Signifies that this link is an edge, i.e. host link. 26 * Signifies that this link is an edge, i.e. host link.
27 */ 27 */
28 - EDGE 28 + EDGE,
29 +
30 + /**
31 + * Signifies that this link represents a logical link backed by
32 + * some form of a tunnel.
33 + */
34 + TUNNEL,
35 +
36 + /**
37 + * Signifies that this link is realized by optical connection.
38 + */
39 + OPTICAL
29 } 40 }
30 41
31 /** 42 /**
...@@ -49,6 +60,4 @@ public interface Link extends Annotated, Provided, NetworkResource { ...@@ -49,6 +60,4 @@ public interface Link extends Annotated, Provided, NetworkResource {
49 */ 60 */
50 Type type(); 61 Type type();
51 62
52 - // LinkInfo info(); // Additional link information / decorations
53 -
54 } 63 }
......
...@@ -7,4 +7,9 @@ import org.onlab.onos.net.provider.Provider; ...@@ -7,4 +7,9 @@ import org.onlab.onos.net.provider.Provider;
7 */ 7 */
8 public interface TopologyProvider extends Provider { 8 public interface TopologyProvider extends Provider {
9 9
10 + /**
11 + * Triggers topology recomputation.
12 + */
13 + void triggerRecompute();
14 +
10 } 15 }
......
...@@ -208,7 +208,7 @@ public class LinkManager ...@@ -208,7 +208,7 @@ public class LinkManager
208 LinkEvent event = store.createOrUpdateLink(provider().id(), 208 LinkEvent event = store.createOrUpdateLink(provider().id(),
209 linkDescription); 209 linkDescription);
210 if (event != null) { 210 if (event != null) {
211 - log.debug("Link {} detected", linkDescription); 211 + log.info("Link {} detected", linkDescription);
212 post(event); 212 post(event);
213 } 213 }
214 } 214 }
......
...@@ -5,6 +5,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -5,6 +5,7 @@ import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Deactivate; 5 import org.apache.felix.scr.annotations.Deactivate;
6 import org.apache.felix.scr.annotations.Reference; 6 import org.apache.felix.scr.annotations.Reference;
7 import org.apache.felix.scr.annotations.ReferenceCardinality; 7 import org.apache.felix.scr.annotations.ReferenceCardinality;
8 +import org.apache.felix.scr.annotations.Service;
8 import org.onlab.onos.event.AbstractEventAccumulator; 9 import org.onlab.onos.event.AbstractEventAccumulator;
9 import org.onlab.onos.event.Event; 10 import org.onlab.onos.event.Event;
10 import org.onlab.onos.event.EventAccumulator; 11 import org.onlab.onos.event.EventAccumulator;
...@@ -39,6 +40,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -39,6 +40,7 @@ import static org.slf4j.LoggerFactory.getLogger;
39 * new topology snapshots. 40 * new topology snapshots.
40 */ 41 */
41 @Component(immediate = true) 42 @Component(immediate = true)
43 +@Service
42 public class DefaultTopologyProvider extends AbstractProvider 44 public class DefaultTopologyProvider extends AbstractProvider
43 implements TopologyProvider { 45 implements TopologyProvider {
44 46
...@@ -89,7 +91,7 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -89,7 +91,7 @@ public class DefaultTopologyProvider extends AbstractProvider
89 linkService.addListener(linkListener); 91 linkService.addListener(linkListener);
90 92
91 isStarted = true; 93 isStarted = true;
92 - triggerTopologyBuild(Collections.<Event>emptyList()); 94 + triggerRecompute();
93 log.info("Started"); 95 log.info("Started");
94 } 96 }
95 97
...@@ -108,6 +110,11 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -108,6 +110,11 @@ public class DefaultTopologyProvider extends AbstractProvider
108 log.info("Stopped"); 110 log.info("Stopped");
109 } 111 }
110 112
113 + @Override
114 + public void triggerRecompute() {
115 + triggerTopologyBuild(Collections.<Event>emptyList());
116 + }
117 +
111 /** 118 /**
112 * Triggers assembly of topology data citing the specified events as the 119 * Triggers assembly of topology data citing the specified events as the
113 * reason. 120 * reason.
...@@ -177,7 +184,11 @@ public class DefaultTopologyProvider extends AbstractProvider ...@@ -177,7 +184,11 @@ public class DefaultTopologyProvider extends AbstractProvider
177 184
178 @Override 185 @Override
179 public void run() { 186 public void run() {
180 - buildTopology(reasons); 187 + try {
188 + buildTopology(reasons);
189 + } catch (Exception e) {
190 + log.warn("Unable to compute topology due to: {}", e.getMessage());
191 + }
181 } 192 }
182 } 193 }
183 194
......
...@@ -195,6 +195,10 @@ public class TopologyManagerTest { ...@@ -195,6 +195,10 @@ public class TopologyManagerTest {
195 public TestProvider() { 195 public TestProvider() {
196 super(PID); 196 super(PID);
197 } 197 }
198 +
199 + @Override
200 + public void triggerRecompute() {
201 + }
198 } 202 }
199 203
200 private static class TestListener implements TopologyListener { 204 private static class TestListener implements TopologyListener {
......
...@@ -192,14 +192,6 @@ public class SimpleLinkStore ...@@ -192,14 +192,6 @@ public class SimpleLinkStore
192 // Creates and stores the link and returns the appropriate event. 192 // Creates and stores the link and returns the appropriate event.
193 // Guarded by linkDescs value (=locking each Link) 193 // Guarded by linkDescs value (=locking each Link)
194 private LinkEvent createLink(LinkKey key, Link newLink) { 194 private LinkEvent createLink(LinkKey key, Link newLink) {
195 -
196 - if (newLink.providerId().isAncillary()) {
197 - // TODO: revisit ancillary only Link handling
198 -
199 - // currently treating ancillary only as down (not visible outside)
200 - return null;
201 - }
202 -
203 links.put(key, newLink); 195 links.put(key, newLink);
204 srcLinks.put(newLink.src().deviceId(), key); 196 srcLinks.put(newLink.src().deviceId(), key);
205 dstLinks.put(newLink.dst().deviceId(), key); 197 dstLinks.put(newLink.dst().deviceId(), key);
...@@ -209,10 +201,8 @@ public class SimpleLinkStore ...@@ -209,10 +201,8 @@ public class SimpleLinkStore
209 // Updates, if necessary the specified link and returns the appropriate event. 201 // Updates, if necessary the specified link and returns the appropriate event.
210 // Guarded by linkDescs value (=locking each Link) 202 // Guarded by linkDescs value (=locking each Link)
211 private LinkEvent updateLink(LinkKey key, Link oldLink, Link newLink) { 203 private LinkEvent updateLink(LinkKey key, Link oldLink, Link newLink) {
212 -
213 if (newLink.providerId().isAncillary()) { 204 if (newLink.providerId().isAncillary()) {
214 // TODO: revisit ancillary only Link handling 205 // TODO: revisit ancillary only Link handling
215 -
216 // currently treating ancillary only as down (not visible outside) 206 // currently treating ancillary only as down (not visible outside)
217 return null; 207 return null;
218 } 208 }
......
1 package org.onlab.onos.store.trivial.impl; 1 package org.onlab.onos.store.trivial.impl;
2 2
3 -import static org.junit.Assert.*; 3 +import com.google.common.collect.Iterables;
4 -import static org.onlab.onos.net.DeviceId.deviceId;
5 -import static org.onlab.onos.net.Link.Type.*;
6 -import static org.onlab.onos.net.link.LinkEvent.Type.*;
7 -import static org.onlab.onos.store.trivial.impl.SimpleDeviceStoreTest.assertAnnotationsEquals;
8 -
9 -import java.util.Collections;
10 -import java.util.HashMap;
11 -import java.util.Map;
12 -import java.util.Set;
13 -import java.util.concurrent.CountDownLatch;
14 -import java.util.concurrent.TimeUnit;
15 -
16 import org.junit.After; 4 import org.junit.After;
17 import org.junit.AfterClass; 5 import org.junit.AfterClass;
18 import org.junit.Before; 6 import org.junit.Before;
...@@ -23,17 +11,27 @@ import org.onlab.onos.net.ConnectPoint; ...@@ -23,17 +11,27 @@ import org.onlab.onos.net.ConnectPoint;
23 import org.onlab.onos.net.DefaultAnnotations; 11 import org.onlab.onos.net.DefaultAnnotations;
24 import org.onlab.onos.net.DeviceId; 12 import org.onlab.onos.net.DeviceId;
25 import org.onlab.onos.net.Link; 13 import org.onlab.onos.net.Link;
14 +import org.onlab.onos.net.Link.Type;
26 import org.onlab.onos.net.LinkKey; 15 import org.onlab.onos.net.LinkKey;
27 import org.onlab.onos.net.PortNumber; 16 import org.onlab.onos.net.PortNumber;
28 import org.onlab.onos.net.SparseAnnotations; 17 import org.onlab.onos.net.SparseAnnotations;
29 -import org.onlab.onos.net.Link.Type;
30 import org.onlab.onos.net.link.DefaultLinkDescription; 18 import org.onlab.onos.net.link.DefaultLinkDescription;
31 import org.onlab.onos.net.link.LinkEvent; 19 import org.onlab.onos.net.link.LinkEvent;
32 import org.onlab.onos.net.link.LinkStore; 20 import org.onlab.onos.net.link.LinkStore;
33 import org.onlab.onos.net.link.LinkStoreDelegate; 21 import org.onlab.onos.net.link.LinkStoreDelegate;
34 import org.onlab.onos.net.provider.ProviderId; 22 import org.onlab.onos.net.provider.ProviderId;
35 23
36 -import com.google.common.collect.Iterables; 24 +import java.util.HashMap;
25 +import java.util.Map;
26 +import java.util.Set;
27 +import java.util.concurrent.CountDownLatch;
28 +import java.util.concurrent.TimeUnit;
29 +
30 +import static org.junit.Assert.*;
31 +import static org.onlab.onos.net.DeviceId.deviceId;
32 +import static org.onlab.onos.net.Link.Type.*;
33 +import static org.onlab.onos.net.link.LinkEvent.Type.*;
34 +import static org.onlab.onos.store.trivial.impl.SimpleDeviceStoreTest.assertAnnotationsEquals;
37 35
38 /** 36 /**
39 * Test of the simple LinkStore implementation. 37 * Test of the simple LinkStore implementation.
...@@ -301,7 +299,7 @@ public class SimpleLinkStoreTest { ...@@ -301,7 +299,7 @@ public class SimpleLinkStoreTest {
301 LinkEvent event = linkStore.createOrUpdateLink(PIDA, 299 LinkEvent event = linkStore.createOrUpdateLink(PIDA,
302 new DefaultLinkDescription(src, dst, INDIRECT, A1)); 300 new DefaultLinkDescription(src, dst, INDIRECT, A1));
303 301
304 - assertNull("Ancillary only link is ignored", event); 302 + assertNotNull("Ancillary only link is ignored", event);
305 303
306 // add Primary link 304 // add Primary link
307 LinkEvent event2 = linkStore.createOrUpdateLink(PID, 305 LinkEvent event2 = linkStore.createOrUpdateLink(PID,
...@@ -309,7 +307,7 @@ public class SimpleLinkStoreTest { ...@@ -309,7 +307,7 @@ public class SimpleLinkStoreTest {
309 307
310 assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject()); 308 assertLink(DID1, P1, DID2, P2, INDIRECT, event2.subject());
311 assertAnnotationsEquals(event2.subject().annotations(), A2, A1); 309 assertAnnotationsEquals(event2.subject().annotations(), A2, A1);
312 - assertEquals(LINK_ADDED, event2.type()); 310 + assertEquals(LINK_UPDATED, event2.type());
313 311
314 // update link type 312 // update link type
315 LinkEvent event3 = linkStore.createOrUpdateLink(PID, 313 LinkEvent event3 = linkStore.createOrUpdateLink(PID,
...@@ -375,7 +373,7 @@ public class SimpleLinkStoreTest { ...@@ -375,7 +373,7 @@ public class SimpleLinkStoreTest {
375 } 373 }
376 374
377 @Test 375 @Test
378 - public final void testAncillaryOnlyNotVisible() { 376 + public final void testAncillaryVisible() {
379 ConnectPoint src = new ConnectPoint(DID1, P1); 377 ConnectPoint src = new ConnectPoint(DID1, P1);
380 ConnectPoint dst = new ConnectPoint(DID2, P2); 378 ConnectPoint dst = new ConnectPoint(DID2, P2);
381 379
...@@ -384,18 +382,8 @@ public class SimpleLinkStoreTest { ...@@ -384,18 +382,8 @@ public class SimpleLinkStoreTest {
384 new DefaultLinkDescription(src, dst, INDIRECT, A1)); 382 new DefaultLinkDescription(src, dst, INDIRECT, A1));
385 383
386 // Ancillary only link should not be visible 384 // Ancillary only link should not be visible
387 - assertEquals(0, linkStore.getLinkCount()); 385 + assertEquals(1, linkStore.getLinkCount());
388 - 386 + assertNotNull(linkStore.getLink(src, dst));
389 - assertTrue(Iterables.isEmpty(linkStore.getLinks()));
390 -
391 - assertNull(linkStore.getLink(src, dst));
392 -
393 - assertEquals(Collections.emptySet(), linkStore.getIngressLinks(dst));
394 -
395 - assertEquals(Collections.emptySet(), linkStore.getEgressLinks(src));
396 -
397 - assertEquals(Collections.emptySet(), linkStore.getDeviceEgressLinks(DID1));
398 - assertEquals(Collections.emptySet(), linkStore.getDeviceIngressLinks(DID2));
399 } 387 }
400 388
401 // If Delegates should be called only on remote events, 389 // If Delegates should be called only on remote events,
......