GUI traffic visualization work on server-side.
Change-Id: I2e903ec028ea40fd325f69c4d7e1f0b2b6db2f42
Showing
2 changed files
with
98 additions
and
61 deletions
| ... | @@ -44,6 +44,7 @@ import org.onlab.onos.net.intent.ConnectivityIntent; | ... | @@ -44,6 +44,7 @@ import org.onlab.onos.net.intent.ConnectivityIntent; |
| 44 | import org.onlab.onos.net.intent.Intent; | 44 | import org.onlab.onos.net.intent.Intent; |
| 45 | import org.onlab.onos.net.intent.IntentService; | 45 | import org.onlab.onos.net.intent.IntentService; |
| 46 | import org.onlab.onos.net.intent.LinkCollectionIntent; | 46 | import org.onlab.onos.net.intent.LinkCollectionIntent; |
| 47 | +import org.onlab.onos.net.intent.OpticalConnectivityIntent; | ||
| 47 | import org.onlab.onos.net.intent.PathIntent; | 48 | import org.onlab.onos.net.intent.PathIntent; |
| 48 | import org.onlab.onos.net.link.LinkEvent; | 49 | import org.onlab.onos.net.link.LinkEvent; |
| 49 | import org.onlab.onos.net.link.LinkService; | 50 | import org.onlab.onos.net.link.LinkService; |
| ... | @@ -88,6 +89,7 @@ public abstract class TopologyMessages { | ... | @@ -88,6 +89,7 @@ public abstract class TopologyMessages { |
| 88 | protected final HostService hostService; | 89 | protected final HostService hostService; |
| 89 | protected final MastershipService mastershipService; | 90 | protected final MastershipService mastershipService; |
| 90 | protected final IntentService intentService; | 91 | protected final IntentService intentService; |
| 92 | +// protected final StatisticService statService; | ||
| 91 | 93 | ||
| 92 | protected final ObjectMapper mapper = new ObjectMapper(); | 94 | protected final ObjectMapper mapper = new ObjectMapper(); |
| 93 | 95 | ||
| ... | @@ -107,6 +109,7 @@ public abstract class TopologyMessages { | ... | @@ -107,6 +109,7 @@ public abstract class TopologyMessages { |
| 107 | hostService = directory.get(HostService.class); | 109 | hostService = directory.get(HostService.class); |
| 108 | mastershipService = directory.get(MastershipService.class); | 110 | mastershipService = directory.get(MastershipService.class); |
| 109 | intentService = directory.get(IntentService.class); | 111 | intentService = directory.get(IntentService.class); |
| 112 | +// statService = directory.get(StatisticService.class); | ||
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | // Retrieves the payload from the specified event. | 115 | // Retrieves the payload from the specified event. |
| ... | @@ -376,10 +379,14 @@ public abstract class TopologyMessages { | ... | @@ -376,10 +379,14 @@ public abstract class TopologyMessages { |
| 376 | 379 | ||
| 377 | for (TrafficClass trafficClass : trafficClasses) { | 380 | for (TrafficClass trafficClass : trafficClasses) { |
| 378 | for (Intent intent : trafficClass.intents) { | 381 | for (Intent intent : trafficClass.intents) { |
| 382 | + boolean isOptical = intent instanceof OpticalConnectivityIntent; | ||
| 379 | List<Intent> installables = intentService.getInstallableIntents(intent.id()); | 383 | List<Intent> installables = intentService.getInstallableIntents(intent.id()); |
| 380 | - for (Intent installable : installables) { | 384 | + if (installables != null) { |
| 381 | - if (installable instanceof ConnectivityIntent) { | 385 | + for (Intent installable : installables) { |
| 382 | - addPathTraffic(paths, trafficClass.type, (ConnectivityIntent) installable); | 386 | + String cls = isOptical ? trafficClass.type + " optical" : trafficClass.type; |
| 387 | + if (installable instanceof ConnectivityIntent) { | ||
| 388 | + addPathTraffic(paths, cls, (ConnectivityIntent) installable); | ||
| 389 | + } | ||
| 383 | } | 390 | } |
| 384 | } | 391 | } |
| 385 | } | 392 | } |
| ... | @@ -395,20 +402,34 @@ public abstract class TopologyMessages { | ... | @@ -395,20 +402,34 @@ public abstract class TopologyMessages { |
| 395 | ObjectNode pathNode = mapper.createObjectNode(); | 402 | ObjectNode pathNode = mapper.createObjectNode(); |
| 396 | ArrayNode linksNode = mapper.createArrayNode(); | 403 | ArrayNode linksNode = mapper.createArrayNode(); |
| 397 | 404 | ||
| 398 | - Iterable<Link> links; | 405 | + Iterable<Link> links = pathLinks(installable); |
| 399 | - if (installable instanceof PathIntent) { | 406 | + if (links != null) { |
| 400 | - links = ((PathIntent) installable).path().links(); | 407 | + ArrayNode labels = mapper.createArrayNode(); |
| 401 | - } else if (installable instanceof LinkCollectionIntent) { | 408 | + boolean hasTraffic = true; // FIXME |
| 402 | - links = ((LinkCollectionIntent) installable).links(); | 409 | + for (Link link : links) { |
| 403 | - } else { | 410 | + linksNode.add(compactLinkString(link)); |
| 404 | - return; | 411 | +// Load load = statService.load(link); |
| 412 | + String label = ""; | ||
| 413 | +// if (load.rate() > 0) { | ||
| 414 | +// label = load.toString(); | ||
| 415 | +// } | ||
| 416 | + labels.add(label); | ||
| 417 | + } | ||
| 418 | + pathNode.put("class", hasTraffic ? type + " animated" : type); | ||
| 419 | + pathNode.put("traffic", hasTraffic); | ||
| 420 | + pathNode.set("links", linksNode); | ||
| 421 | + pathNode.set("labels", labels); | ||
| 422 | + paths.add(pathNode); | ||
| 405 | } | 423 | } |
| 424 | + } | ||
| 406 | 425 | ||
| 407 | - for (Link link : links) { | 426 | + private Iterable<Link> pathLinks(ConnectivityIntent intent) { |
| 408 | - linksNode.add(compactLinkString(link)); | 427 | + if (intent instanceof PathIntent) { |
| 428 | + return ((PathIntent) intent).path().links(); | ||
| 429 | + } else if (intent instanceof LinkCollectionIntent) { | ||
| 430 | + return ((LinkCollectionIntent) intent).links(); | ||
| 409 | } | 431 | } |
| 410 | - pathNode.put("type", type).set("links", linksNode); | 432 | + return null; |
| 411 | - paths.add(pathNode); | ||
| 412 | } | 433 | } |
| 413 | 434 | ||
| 414 | // Produces compact string representation of a link. | 435 | // Produces compact string representation of a link. | ... | ... |
| ... | @@ -24,8 +24,6 @@ import org.onlab.onos.cluster.ClusterEventListener; | ... | @@ -24,8 +24,6 @@ import org.onlab.onos.cluster.ClusterEventListener; |
| 24 | import org.onlab.onos.cluster.ControllerNode; | 24 | import org.onlab.onos.cluster.ControllerNode; |
| 25 | import org.onlab.onos.core.ApplicationId; | 25 | import org.onlab.onos.core.ApplicationId; |
| 26 | import org.onlab.onos.core.CoreService; | 26 | import org.onlab.onos.core.CoreService; |
| 27 | -import org.onlab.onos.mastership.MastershipEvent; | ||
| 28 | -import org.onlab.onos.mastership.MastershipListener; | ||
| 29 | import org.onlab.onos.net.ConnectPoint; | 27 | import org.onlab.onos.net.ConnectPoint; |
| 30 | import org.onlab.onos.net.Device; | 28 | import org.onlab.onos.net.Device; |
| 31 | import org.onlab.onos.net.Host; | 29 | import org.onlab.onos.net.Host; |
| ... | @@ -43,6 +41,7 @@ import org.onlab.onos.net.intent.Intent; | ... | @@ -43,6 +41,7 @@ import org.onlab.onos.net.intent.Intent; |
| 43 | import org.onlab.onos.net.intent.IntentEvent; | 41 | import org.onlab.onos.net.intent.IntentEvent; |
| 44 | import org.onlab.onos.net.intent.IntentListener; | 42 | import org.onlab.onos.net.intent.IntentListener; |
| 45 | import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; | 43 | import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; |
| 44 | +import org.onlab.onos.net.intent.OpticalConnectivityIntent; | ||
| 46 | import org.onlab.onos.net.intent.PathIntent; | 45 | import org.onlab.onos.net.intent.PathIntent; |
| 47 | import org.onlab.onos.net.intent.PointToPointIntent; | 46 | import org.onlab.onos.net.intent.PointToPointIntent; |
| 48 | import org.onlab.onos.net.link.LinkEvent; | 47 | import org.onlab.onos.net.link.LinkEvent; |
| ... | @@ -52,9 +51,9 @@ import org.onlab.osgi.ServiceDirectory; | ... | @@ -52,9 +51,9 @@ import org.onlab.osgi.ServiceDirectory; |
| 52 | import java.io.IOException; | 51 | import java.io.IOException; |
| 53 | import java.util.HashSet; | 52 | import java.util.HashSet; |
| 54 | import java.util.List; | 53 | import java.util.List; |
| 55 | -import java.util.Map; | ||
| 56 | import java.util.Set; | 54 | import java.util.Set; |
| 57 | -import java.util.concurrent.ConcurrentHashMap; | 55 | +import java.util.Timer; |
| 56 | +import java.util.TimerTask; | ||
| 58 | 57 | ||
| 59 | import static com.google.common.base.Strings.isNullOrEmpty; | 58 | import static com.google.common.base.Strings.isNullOrEmpty; |
| 60 | import static org.onlab.onos.cluster.ClusterEvent.Type.INSTANCE_ADDED; | 59 | import static org.onlab.onos.cluster.ClusterEvent.Type.INSTANCE_ADDED; |
| ... | @@ -62,6 +61,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; | ... | @@ -62,6 +61,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; |
| 62 | import static org.onlab.onos.net.HostId.hostId; | 61 | import static org.onlab.onos.net.HostId.hostId; |
| 63 | import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_ADDED; | 62 | import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_ADDED; |
| 64 | import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED; | 63 | import static org.onlab.onos.net.host.HostEvent.Type.HOST_ADDED; |
| 64 | +import static org.onlab.onos.net.intent.IntentState.INSTALLED; | ||
| 65 | import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED; | 65 | import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED; |
| 66 | 66 | ||
| 67 | /** | 67 | /** |
| ... | @@ -79,6 +79,8 @@ public class TopologyWebSocket | ... | @@ -79,6 +79,8 @@ public class TopologyWebSocket |
| 79 | 79 | ||
| 80 | private static final String APP_ID = "org.onlab.onos.gui"; | 80 | private static final String APP_ID = "org.onlab.onos.gui"; |
| 81 | 81 | ||
| 82 | + private static final long TRAFFIC_FREQUENCY_SEC = 5000; | ||
| 83 | + | ||
| 82 | private final ApplicationId appId; | 84 | private final ApplicationId appId; |
| 83 | 85 | ||
| 84 | private Connection connection; | 86 | private Connection connection; |
| ... | @@ -88,11 +90,12 @@ public class TopologyWebSocket | ... | @@ -88,11 +90,12 @@ public class TopologyWebSocket |
| 88 | private final DeviceListener deviceListener = new InternalDeviceListener(); | 90 | private final DeviceListener deviceListener = new InternalDeviceListener(); |
| 89 | private final LinkListener linkListener = new InternalLinkListener(); | 91 | private final LinkListener linkListener = new InternalLinkListener(); |
| 90 | private final HostListener hostListener = new InternalHostListener(); | 92 | private final HostListener hostListener = new InternalHostListener(); |
| 91 | - private final MastershipListener mastershipListener = new InternalMastershipListener(); | ||
| 92 | private final IntentListener intentListener = new InternalIntentListener(); | 93 | private final IntentListener intentListener = new InternalIntentListener(); |
| 93 | 94 | ||
| 94 | // Intents that are being monitored for the GUI | 95 | // Intents that are being monitored for the GUI |
| 95 | - private Map<Intent, Long> intentsToMonitor = new ConcurrentHashMap<>(); | 96 | + private ObjectNode monitorRequest; |
| 97 | + private final Timer timer = new Timer("intent-traffic-monitor"); | ||
| 98 | + private final TimerTask timerTask = new IntentTrafficMonitor(); | ||
| 96 | 99 | ||
| 97 | private long lastActive = System.currentTimeMillis(); | 100 | private long lastActive = System.currentTimeMillis(); |
| 98 | private boolean listenersRemoved = false; | 101 | private boolean listenersRemoved = false; |
| ... | @@ -141,6 +144,7 @@ public class TopologyWebSocket | ... | @@ -141,6 +144,7 @@ public class TopologyWebSocket |
| 141 | this.connection = connection; | 144 | this.connection = connection; |
| 142 | this.control = (FrameConnection) connection; | 145 | this.control = (FrameConnection) connection; |
| 143 | addListeners(); | 146 | addListeners(); |
| 147 | + timer.schedule(timerTask, TRAFFIC_FREQUENCY_SEC, TRAFFIC_FREQUENCY_SEC); | ||
| 144 | 148 | ||
| 145 | sendAllInstances(); | 149 | sendAllInstances(); |
| 146 | sendAllDevices(); | 150 | sendAllDevices(); |
| ... | @@ -151,6 +155,7 @@ public class TopologyWebSocket | ... | @@ -151,6 +155,7 @@ public class TopologyWebSocket |
| 151 | @Override | 155 | @Override |
| 152 | public synchronized void onClose(int closeCode, String message) { | 156 | public synchronized void onClose(int closeCode, String message) { |
| 153 | removeListeners(); | 157 | removeListeners(); |
| 158 | + timer.cancel(); | ||
| 154 | log.info("GUI client disconnected"); | 159 | log.info("GUI client disconnected"); |
| 155 | } | 160 | } |
| 156 | 161 | ||
| ... | @@ -245,14 +250,15 @@ public class TopologyWebSocket | ... | @@ -245,14 +250,15 @@ public class TopologyWebSocket |
| 245 | HostToHostIntent hostIntent = new HostToHostIntent(appId, one, two, | 250 | HostToHostIntent hostIntent = new HostToHostIntent(appId, one, two, |
| 246 | DefaultTrafficSelector.builder().build(), | 251 | DefaultTrafficSelector.builder().build(), |
| 247 | DefaultTrafficTreatment.builder().build()); | 252 | DefaultTrafficTreatment.builder().build()); |
| 248 | - intentsToMonitor.put(hostIntent, number(event, "sid")); | 253 | + monitorRequest = event; |
| 249 | intentService.submit(hostIntent); | 254 | intentService.submit(hostIntent); |
| 250 | } | 255 | } |
| 251 | 256 | ||
| 252 | // Sends traffic message. | 257 | // Sends traffic message. |
| 253 | - private void requestTraffic(ObjectNode event) { | 258 | + private synchronized void requestTraffic(ObjectNode event) { |
| 254 | ObjectNode payload = payload(event); | 259 | ObjectNode payload = payload(event); |
| 255 | long sid = number(event, "sid"); | 260 | long sid = number(event, "sid"); |
| 261 | + monitorRequest = event; | ||
| 256 | 262 | ||
| 257 | // Get the set of selected hosts and their intents. | 263 | // Get the set of selected hosts and their intents. |
| 258 | Set<Host> hosts = getHosts((ArrayNode) payload.path("ids")); | 264 | Set<Host> hosts = getHosts((ArrayNode) payload.path("ids")); |
| ... | @@ -274,18 +280,13 @@ public class TopologyWebSocket | ... | @@ -274,18 +280,13 @@ public class TopologyWebSocket |
| 274 | } else { | 280 | } else { |
| 275 | // Send an initial message to highlight all links of all monitored intents. | 281 | // Send an initial message to highlight all links of all monitored intents. |
| 276 | sendMessage(trafficMessage(sid, new TrafficClass("primary", intents))); | 282 | sendMessage(trafficMessage(sid, new TrafficClass("primary", intents))); |
| 277 | - | ||
| 278 | - // Add all those intents to the list of monitored intents & flows. | ||
| 279 | - intentsToMonitor.clear(); | ||
| 280 | - for (Intent intent : intents) { | ||
| 281 | - intentsToMonitor.put(intent, sid); | ||
| 282 | - } | ||
| 283 | } | 283 | } |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | // Cancels sending traffic messages. | 286 | // Cancels sending traffic messages. |
| 287 | private void cancelTraffic(ObjectNode event) { | 287 | private void cancelTraffic(ObjectNode event) { |
| 288 | sendMessage(trafficMessage(number(event, "sid"))); | 288 | sendMessage(trafficMessage(number(event, "sid"))); |
| 289 | + monitorRequest = null; | ||
| 289 | } | 290 | } |
| 290 | 291 | ||
| 291 | // Finds all path (host-to-host or point-to-point) intents that pertains | 292 | // Finds all path (host-to-host or point-to-point) intents that pertains |
| ... | @@ -306,18 +307,30 @@ public class TopologyWebSocket | ... | @@ -306,18 +307,30 @@ public class TopologyWebSocket |
| 306 | return intents; | 307 | return intents; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 310 | + Set<OpticalConnectivityIntent> opticalIntents = new HashSet<>(); | ||
| 311 | + | ||
| 309 | for (Intent intent : intentService.getIntents()) { | 312 | for (Intent intent : intentService.getIntents()) { |
| 310 | - boolean isRelevant = false; | 313 | + if (intentService.getIntentState(intent.id()) == INSTALLED) { |
| 311 | - if (intent instanceof HostToHostIntent) { | 314 | + boolean isRelevant = false; |
| 312 | - isRelevant = isIntentRelevant((HostToHostIntent) intent, hosts); | 315 | + if (intent instanceof HostToHostIntent) { |
| 313 | - } else if (intent instanceof PointToPointIntent) { | 316 | + isRelevant = isIntentRelevant((HostToHostIntent) intent, hosts); |
| 314 | - isRelevant = isIntentRelevant((PointToPointIntent) intent, edgePoints); | 317 | + } else if (intent instanceof PointToPointIntent) { |
| 315 | - } else if (intent instanceof MultiPointToSinglePointIntent) { | 318 | + isRelevant = isIntentRelevant((PointToPointIntent) intent, edgePoints); |
| 316 | - isRelevant = isIntentRelevant((MultiPointToSinglePointIntent) intent, edgePoints); | 319 | + } else if (intent instanceof MultiPointToSinglePointIntent) { |
| 320 | + isRelevant = isIntentRelevant((MultiPointToSinglePointIntent) intent, edgePoints); | ||
| 321 | + } else if (intent instanceof OpticalConnectivityIntent) { | ||
| 322 | + opticalIntents.add((OpticalConnectivityIntent) intent); | ||
| 323 | + } | ||
| 324 | + // TODO: add other intents, e.g. SinglePointToMultiPointIntent | ||
| 325 | + | ||
| 326 | + if (isRelevant) { | ||
| 327 | + intents.add(intent); | ||
| 328 | + } | ||
| 317 | } | 329 | } |
| 318 | - // TODO: add other intents, e.g. SinglePointToMultiPointIntent | 330 | + } |
| 319 | 331 | ||
| 320 | - if (isRelevant) { | 332 | + for (OpticalConnectivityIntent intent : opticalIntents) { |
| 333 | + if (isIntentRelevant(intent, intents)) { | ||
| 321 | intents.add(intent); | 334 | intents.add(intent); |
| 322 | } | 335 | } |
| 323 | } | 336 | } |
| ... | @@ -362,6 +375,23 @@ public class TopologyWebSocket | ... | @@ -362,6 +375,23 @@ public class TopologyWebSocket |
| 362 | return true; | 375 | return true; |
| 363 | } | 376 | } |
| 364 | 377 | ||
| 378 | + // Indicates whether the specified intent involves all of the given edge points. | ||
| 379 | + private boolean isIntentRelevant(OpticalConnectivityIntent opticalIntent, | ||
| 380 | + Set<Intent> intents) { | ||
| 381 | + for (Intent intent : intents) { | ||
| 382 | + List<Intent> installables = intentService.getInstallableIntents(intent.id()); | ||
| 383 | + for (Intent installable : installables) { | ||
| 384 | + if (installable instanceof PathIntent) { | ||
| 385 | + Path path = ((PathIntent) installable).path(); | ||
| 386 | + if (opticalIntent.getSrcConnectPoint().equals(path.src()) && | ||
| 387 | + opticalIntent.getDst().equals(path.dst())) { | ||
| 388 | + return true; | ||
| 389 | + } | ||
| 390 | + } | ||
| 391 | + } | ||
| 392 | + } | ||
| 393 | + return false; | ||
| 394 | + } | ||
| 365 | 395 | ||
| 366 | // Produces a set of all host ids listed in the specified JSON array. | 396 | // Produces a set of all host ids listed in the specified JSON array. |
| 367 | private Set<Host> getHosts(ArrayNode array) { | 397 | private Set<Host> getHosts(ArrayNode array) { |
| ... | @@ -401,7 +431,6 @@ public class TopologyWebSocket | ... | @@ -401,7 +431,6 @@ public class TopologyWebSocket |
| 401 | deviceService.addListener(deviceListener); | 431 | deviceService.addListener(deviceListener); |
| 402 | linkService.addListener(linkListener); | 432 | linkService.addListener(linkListener); |
| 403 | hostService.addListener(hostListener); | 433 | hostService.addListener(hostListener); |
| 404 | - mastershipService.addListener(mastershipListener); | ||
| 405 | intentService.addListener(intentListener); | 434 | intentService.addListener(intentListener); |
| 406 | } | 435 | } |
| 407 | 436 | ||
| ... | @@ -413,7 +442,6 @@ public class TopologyWebSocket | ... | @@ -413,7 +442,6 @@ public class TopologyWebSocket |
| 413 | deviceService.removeListener(deviceListener); | 442 | deviceService.removeListener(deviceListener); |
| 414 | linkService.removeListener(linkListener); | 443 | linkService.removeListener(linkListener); |
| 415 | hostService.removeListener(hostListener); | 444 | hostService.removeListener(hostListener); |
| 416 | - mastershipService.removeListener(mastershipListener); | ||
| 417 | intentService.removeListener(intentListener); | 445 | intentService.removeListener(intentListener); |
| 418 | } | 446 | } |
| 419 | } | 447 | } |
| ... | @@ -450,35 +478,23 @@ public class TopologyWebSocket | ... | @@ -450,35 +478,23 @@ public class TopologyWebSocket |
| 450 | } | 478 | } |
| 451 | } | 479 | } |
| 452 | 480 | ||
| 453 | - // Mastership event listener. | ||
| 454 | - private class InternalMastershipListener implements MastershipListener { | ||
| 455 | - @Override | ||
| 456 | - public void event(MastershipEvent event) { | ||
| 457 | - // TODO: Is DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED the same? | ||
| 458 | - | ||
| 459 | - } | ||
| 460 | - } | ||
| 461 | - | ||
| 462 | // Intent event listener. | 481 | // Intent event listener. |
| 463 | private class InternalIntentListener implements IntentListener { | 482 | private class InternalIntentListener implements IntentListener { |
| 464 | @Override | 483 | @Override |
| 465 | public void event(IntentEvent event) { | 484 | public void event(IntentEvent event) { |
| 466 | - Intent intent = event.subject(); | 485 | + if (monitorRequest != null) { |
| 467 | - Long sid = intentsToMonitor.get(intent); | 486 | + requestTraffic(monitorRequest); |
| 468 | - if (sid != null) { | ||
| 469 | - List<Intent> installable = intentService.getInstallableIntents(intent.id()); | ||
| 470 | - if (installable != null && !installable.isEmpty()) { | ||
| 471 | - PathIntent pathIntent = (PathIntent) installable.iterator().next(); | ||
| 472 | - Path path = pathIntent.path(); | ||
| 473 | - ObjectNode payload = pathMessage(path, "host") | ||
| 474 | - .put("intentId", intent.id().toString()); | ||
| 475 | - sendMessage(envelope("showPath", sid, payload)); | ||
| 476 | - TrafficClass tc = new TrafficClass("animated", intentsToMonitor.keySet()); | ||
| 477 | - sendMessage(trafficMessage(sid, tc)); | ||
| 478 | - } | ||
| 479 | } | 487 | } |
| 480 | } | 488 | } |
| 481 | } | 489 | } |
| 482 | 490 | ||
| 491 | + private class IntentTrafficMonitor extends TimerTask { | ||
| 492 | + @Override | ||
| 493 | + public void run() { | ||
| 494 | + if (monitorRequest != null) { | ||
| 495 | + requestTraffic(monitorRequest); | ||
| 496 | + } | ||
| 497 | + } | ||
| 498 | + } | ||
| 483 | } | 499 | } |
| 484 | 500 | ... | ... |
-
Please register or login to post a comment