Ayaka Koshibe
Committed by Pavlin Radoslavov

File read properly updates topology information

Change-Id: I1e78e06e701cef45e5454d6e928967187174f8e5
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.provider.nil.link.impl; 16 package org.onosproject.provider.nil.link.impl;
17 17
18 +import com.google.common.collect.HashMultimap;
18 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
20 import com.google.common.collect.Sets; 21 import com.google.common.collect.Sets;
...@@ -49,7 +50,6 @@ import org.slf4j.Logger; ...@@ -49,7 +50,6 @@ import org.slf4j.Logger;
49 import java.util.Dictionary; 50 import java.util.Dictionary;
50 import java.util.Iterator; 51 import java.util.Iterator;
51 import java.util.List; 52 import java.util.List;
52 -import java.util.ArrayList;
53 import java.util.Set; 53 import java.util.Set;
54 import java.util.concurrent.ConcurrentMap; 54 import java.util.concurrent.ConcurrentMap;
55 import java.util.concurrent.Executors; 55 import java.util.concurrent.Executors;
...@@ -87,6 +87,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -87,6 +87,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
87 private static final int CHECK_DURATION = 10; 87 private static final int CHECK_DURATION = 10;
88 private static final int DEFAULT_RATE = 0; // usec 88 private static final int DEFAULT_RATE = 0; // usec
89 private static final int REFRESH_RATE = 3; // sec 89 private static final int REFRESH_RATE = 3; // sec
90 + private static final DeviceId DEFAULT = DeviceId.deviceId("null:ffffffffffffffff");
90 91
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected DeviceService deviceService; 93 protected DeviceService deviceService;
...@@ -109,10 +110,10 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -109,10 +110,10 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
109 .newConcurrentMap(); 110 .newConcurrentMap();
110 111
111 // Link descriptions 112 // Link descriptions
112 - private final Set<LinkDescription> linkDescrs = Sets.newConcurrentHashSet(); 113 + private final List<LinkDescription> linkDescrs = Lists.newArrayList();
113 114
114 // Thread to description map 115 // Thread to description map
115 - private final List<Set<LinkDescription>> linkTasks = new ArrayList<>(THREADS); 116 + private final List<List<LinkDescription>> linkTasks = Lists.newArrayList();
116 117
117 private ScheduledExecutorService linkDriver = 118 private ScheduledExecutorService linkDriver =
118 Executors.newScheduledThreadPool(THREADS, groupedThreads("onos/null", "link-driver-%d")); 119 Executors.newScheduledThreadPool(THREADS, groupedThreads("onos/null", "link-driver-%d"));
...@@ -140,10 +141,9 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -140,10 +141,9 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
140 modified(context); 141 modified(context);
141 142
142 if (flicker) { 143 if (flicker) {
143 - allocateLinks();
144 for (int i = 0; i < linkTasks.size(); i++) { 144 for (int i = 0; i < linkTasks.size(); i++) {
145 - Set<LinkDescription> links = linkTasks.get(i); 145 + List<LinkDescription> links = linkTasks.get(i);
146 - LinkDriver driver = new LinkDriver(links, i); 146 + LinkDriver driver = new LinkDriver(links);
147 links.forEach(v -> { 147 links.forEach(v -> {
148 DeviceId d = v.src().deviceId(); 148 DeviceId d = v.src().deviceId();
149 Set<LinkDriver> s = driverMap.getOrDefault(d, Sets.newConcurrentHashSet()); 149 Set<LinkDriver> s = driverMap.getOrDefault(d, Sets.newConcurrentHashSet());
...@@ -157,7 +157,9 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -157,7 +157,9 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
157 } 157 }
158 } 158 }
159 } else { 159 } else {
160 - linkDriver.schedule(new LinkDriver(linkDescrs, 0), 3, TimeUnit.SECONDS); 160 + LinkDriver driver = new LinkDriver(linkDescrs);
161 + driverMap.put(DEFAULT, Sets.newHashSet(driver));
162 + linkDriver.schedule(driver, 3, TimeUnit.SECONDS);
161 } 163 }
162 log.info("started"); 164 log.info("started");
163 } 165 }
...@@ -208,8 +210,12 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -208,8 +210,12 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
208 if (eventRate != newRate && newRate > 0) { 210 if (eventRate != newRate && newRate > 0) {
209 eventRate = newRate; 211 eventRate = newRate;
210 flicker = true; 212 flicker = true;
213 + allocateLinks();
211 } else if (newRate == 0) { 214 } else if (newRate == 0) {
212 flicker = false; 215 flicker = false;
216 + // reconfigure driver - dumb but should work.
217 + driverMap.getOrDefault(DEFAULT, Sets.newHashSet()).forEach(
218 + v -> v.setTasks(linkDescrs));
213 } 219 }
214 220
215 log.info("Using settings: eventRate={}, topofile={}", eventRate, cfgFile); 221 log.info("Using settings: eventRate={}, topofile={}", eventRate, cfgFile);
...@@ -218,6 +224,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -218,6 +224,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
218 // parse simplified dot-like topology graph 224 // parse simplified dot-like topology graph
219 private void readGraph(String path, NodeId me) { 225 private void readGraph(String path, NodeId me) {
220 log.info("path: {}, local: {}", path, me); 226 log.info("path: {}, local: {}", path, me);
227 + Set<LinkDescription> read = Sets.newHashSet();
221 BufferedReader br = null; 228 BufferedReader br = null;
222 try { 229 try {
223 br = new BufferedReader(new FileReader(path)); 230 br = new BufferedReader(new FileReader(path));
...@@ -239,7 +246,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -239,7 +246,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
239 if (cur.trim().contains("}")) { 246 if (cur.trim().contains("}")) {
240 break; 247 break;
241 } 248 }
242 - readLink(cur.trim().split(" "), me); 249 + readLink(cur.trim().split(" "), me, read);
243 cur = br.readLine(); 250 cur = br.readLine();
244 } 251 }
245 } else { 252 } else {
...@@ -264,10 +271,16 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -264,10 +271,16 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
264 log.warn("Could not close topology file: {}", e); 271 log.warn("Could not close topology file: {}", e);
265 } 272 }
266 } 273 }
274 + synchronized (linkDescrs) {
275 + if (!read.isEmpty()) {
276 + linkDescrs.clear();
277 + linkDescrs.addAll(read);
278 + }
279 + }
267 } 280 }
268 281
269 // parses a link descriptor to make a LinkDescription 282 // parses a link descriptor to make a LinkDescription
270 - private void readLink(String[] linkArr, NodeId me) { 283 + private void readLink(String[] linkArr, NodeId me, Set<LinkDescription> links) {
271 if (linkArr[0].startsWith("#")) { 284 if (linkArr[0].startsWith("#")) {
272 return; 285 return;
273 } 286 }
...@@ -302,11 +315,11 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -302,11 +315,11 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
302 ConnectPoint dst = new ConnectPoint(ddev, PortNumber.portNumber(cp2[1])); 315 ConnectPoint dst = new ConnectPoint(ddev, PortNumber.portNumber(cp2[1]));
303 // both link types have incoming half-link 316 // both link types have incoming half-link
304 LinkDescription in = new DefaultLinkDescription(dst, src, DIRECT); 317 LinkDescription in = new DefaultLinkDescription(dst, src, DIRECT);
305 - linkDescrs.add(in); 318 + links.add(in);
306 if (op.equals("--")) { 319 if (op.equals("--")) {
307 // bidirectional - within our node's island, make outbound link 320 // bidirectional - within our node's island, make outbound link
308 LinkDescription out = new DefaultLinkDescription(src, dst, DIRECT); 321 LinkDescription out = new DefaultLinkDescription(src, dst, DIRECT);
309 - linkDescrs.add(out); 322 + links.add(out);
310 log.info("Created bidirectional link: {}, {}", out, in); 323 log.info("Created bidirectional link: {}, {}", out, in);
311 } else if (op.equals("->")) { 324 } else if (op.equals("->")) {
312 log.info("Created unidirectional link: {}", in); 325 log.info("Created unidirectional link: {}", in);
...@@ -336,7 +349,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -336,7 +349,7 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
336 index = (lcount % THREADS); 349 index = (lcount % THREADS);
337 log.info("allocation: total={}, index={}", linkDescrs.size(), lcount, index); 350 log.info("allocation: total={}, index={}", linkDescrs.size(), lcount, index);
338 if (linkTasks.size() <= index) { 351 if (linkTasks.size() <= index) {
339 - linkTasks.add(index, Sets.newHashSet(ld)); 352 + linkTasks.add(index, Lists.newArrayList(ld));
340 } else { 353 } else {
341 linkTasks.get(index).add(ld); 354 linkTasks.get(index).add(ld);
342 } 355 }
...@@ -383,16 +396,13 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -383,16 +396,13 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
383 396
384 long startTime; 397 long startTime;
385 398
386 - LinkDriver(Set<LinkDescription> links, int index) { 399 + LinkDriver(List<LinkDescription> links) {
387 - for (LinkDescription link : links) { 400 + setTasks(links);
388 - tasks.add(link); 401 + startTime = System.currentTimeMillis(); // yes, this will start off inaccurate
389 - }
390 - startTime = System.currentTimeMillis();
391 } 402 }
392 403
393 @Override 404 @Override
394 public void run() { 405 public void run() {
395 - log.info("Thread started for links {}", tasks);
396 if (flicker) { 406 if (flicker) {
397 flicker(); 407 flicker();
398 } else { 408 } else {
...@@ -428,9 +438,9 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -428,9 +438,9 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
428 438
429 private void refresh() { 439 private void refresh() {
430 if (!linkDriver.isShutdown() || !tasks.isEmpty()) { 440 if (!linkDriver.isShutdown() || !tasks.isEmpty()) {
431 - log.info("iter {} refresh_links for {} links", counter, linkDescrs.size()); 441 + log.info("iter {} refresh_links", counter);
432 442
433 - for (LinkDescription desc : linkDescrs) { 443 + for (LinkDescription desc : tasks) {
434 providerService.linkDetected(desc); 444 providerService.linkDetected(desc);
435 log.info("iteration {}, {}", counter, desc); 445 log.info("iteration {}, {}", counter, desc);
436 } 446 }
...@@ -451,6 +461,21 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider { ...@@ -451,6 +461,21 @@ public class NullLinkProvider extends AbstractProvider implements LinkProvider {
451 } 461 }
452 } 462 }
453 } 463 }
464 +
465 + public void setTasks(List<LinkDescription> links) {
466 + HashMultimap<ConnectPoint, ConnectPoint> nm = HashMultimap.create();
467 + links.forEach(v -> nm.put(v.src(), v.dst()));
468 + // remove and send linkVanished for stale links.
469 + synchronized (this) {
470 + for (LinkDescription l : tasks) {
471 + if (!nm.containsEntry(l.src(), l.dst())) {
472 + providerService.linkVanished(l);
473 + }
474 + }
475 + tasks.clear();
476 + tasks.addAll(links);
477 + }
478 + }
454 } 479 }
455 480
456 } 481 }
......