blob: 2a66b8e3809aca074fadcfe9a1803fd7c90ac497 [file] [log] [blame]
Simon Hunted804d52016-03-30 09:51:40 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Simon Hunted804d52016-03-30 09:51:40 -07003 *
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
17package org.onosproject.ui.impl.topo.model;
18
Simon Huntcda9c032016-04-11 10:32:54 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
Madan Jampani492526a2016-06-06 17:24:04 -070025import org.onlab.util.Tools;
Simon Hunt7092cc42016-04-06 18:40:17 -070026import org.onosproject.cluster.ClusterEvent;
27import org.onosproject.cluster.ClusterEventListener;
28import org.onosproject.cluster.ClusterService;
Simon Hunt23fb1352016-04-11 12:15:19 -070029import org.onosproject.cluster.ControllerNode;
30import org.onosproject.cluster.RoleInfo;
Simon Huntcda9c032016-04-11 10:32:54 -070031import org.onosproject.event.AbstractListenerManager;
Simon Hunt7092cc42016-04-06 18:40:17 -070032import org.onosproject.incubator.net.PortStatisticsService;
33import org.onosproject.incubator.net.tunnel.TunnelService;
34import org.onosproject.mastership.MastershipEvent;
35import org.onosproject.mastership.MastershipListener;
36import org.onosproject.mastership.MastershipService;
Simon Huntcda9c032016-04-11 10:32:54 -070037import org.onosproject.net.Device;
Simon Hunt23fb1352016-04-11 12:15:19 -070038import org.onosproject.net.DeviceId;
39import org.onosproject.net.Host;
40import org.onosproject.net.Link;
Simon Hunt7092cc42016-04-06 18:40:17 -070041import org.onosproject.net.device.DeviceEvent;
42import org.onosproject.net.device.DeviceListener;
43import org.onosproject.net.device.DeviceService;
44import org.onosproject.net.flow.FlowRuleEvent;
45import org.onosproject.net.flow.FlowRuleListener;
46import org.onosproject.net.flow.FlowRuleService;
47import org.onosproject.net.host.HostEvent;
48import org.onosproject.net.host.HostListener;
49import org.onosproject.net.host.HostService;
50import org.onosproject.net.intent.IntentEvent;
51import org.onosproject.net.intent.IntentListener;
52import org.onosproject.net.intent.IntentService;
53import org.onosproject.net.link.LinkEvent;
54import org.onosproject.net.link.LinkListener;
55import org.onosproject.net.link.LinkService;
Simon Hunt23fb1352016-04-11 12:15:19 -070056import org.onosproject.net.region.Region;
Simon Hunt7092cc42016-04-06 18:40:17 -070057import org.onosproject.net.region.RegionEvent;
Simon Hunt977aa052016-07-20 17:08:29 -070058import org.onosproject.net.region.RegionId;
Simon Hunt7092cc42016-04-06 18:40:17 -070059import org.onosproject.net.region.RegionListener;
60import org.onosproject.net.region.RegionService;
61import org.onosproject.net.statistic.StatisticService;
62import org.onosproject.net.topology.TopologyService;
Simon Hunt4f4ffc32016-08-03 18:30:47 -070063import org.onosproject.ui.UiTopoLayoutService;
Simon Huntf679c4e2016-04-01 17:02:24 -070064import org.onosproject.ui.impl.topo.UiTopoSession;
Simon Hunt642bc452016-05-04 19:34:45 -070065import org.onosproject.ui.model.ServiceBundle;
Simon Huntd5b96732016-07-08 13:22:27 -070066import org.onosproject.ui.model.topo.UiClusterMember;
Simon Hunt4854f3d2016-08-02 18:13:15 -070067import org.onosproject.ui.model.topo.UiDevice;
Simon Huntc13082f2016-08-03 21:20:23 -070068import org.onosproject.ui.model.topo.UiDeviceLink;
Simon Hunt4854f3d2016-08-02 18:13:15 -070069import org.onosproject.ui.model.topo.UiHost;
Simon Huntd5b96732016-07-08 13:22:27 -070070import org.onosproject.ui.model.topo.UiRegion;
Simon Huntc13082f2016-08-03 21:20:23 -070071import org.onosproject.ui.model.topo.UiSynthLink;
Simon Hunted804d52016-03-30 09:51:40 -070072import org.slf4j.Logger;
73import org.slf4j.LoggerFactory;
74
Simon Huntd5b96732016-07-08 13:22:27 -070075import java.util.List;
Simon Hunt10973dd2016-08-01 15:50:35 -070076import java.util.Set;
Simon Huntd5b96732016-07-08 13:22:27 -070077import java.util.concurrent.ExecutorService;
78import java.util.concurrent.Executors;
79
Simon Hunted804d52016-03-30 09:51:40 -070080/**
Simon Huntcda9c032016-04-11 10:32:54 -070081 * Service that creates and maintains the UI-model of the network topology.
Simon Hunted804d52016-03-30 09:51:40 -070082 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070083@Component(immediate = true, enabled = true)
Simon Huntcda9c032016-04-11 10:32:54 -070084@Service(value = UiSharedTopologyModel.class)
85public final class UiSharedTopologyModel
86 extends AbstractListenerManager<UiModelEvent, UiModelListener> {
Simon Hunted804d52016-03-30 09:51:40 -070087
88 private static final Logger log =
89 LoggerFactory.getLogger(UiSharedTopologyModel.class);
90
Simon Huntcda9c032016-04-11 10:32:54 -070091 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Simon Hunt4f4ffc32016-08-03 18:30:47 -070092 private UiTopoLayoutService layoutService;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Simon Huntcda9c032016-04-11 10:32:54 -070095 private ClusterService clusterService;
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 private MastershipService mastershipService;
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 private RegionService regionService;
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 private DeviceService deviceService;
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 private LinkService linkService;
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 private HostService hostService;
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 private IntentService intentService;
108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 private FlowRuleService flowService;
Simon Hunt7092cc42016-04-06 18:40:17 -0700110
Simon Huntcda9c032016-04-11 10:32:54 -0700111 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
112 private StatisticService flowStatsService;
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 private PortStatisticsService portStatsService;
115 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
116 private TopologyService topologyService;
117 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
118 private TunnelService tunnelService;
Simon Hunted804d52016-03-30 09:51:40 -0700119
Simon Huntcda9c032016-04-11 10:32:54 -0700120 private final ClusterEventListener clusterListener =
121 new InternalClusterListener();
122 private final MastershipListener mastershipListener =
123 new InternalMastershipListener();
124 private final RegionListener regionListener =
125 new InternalRegionListener();
126 private final DeviceListener deviceListener =
127 new InternalDeviceListener();
128 private final LinkListener linkListener =
129 new InternalLinkListener();
130 private final HostListener hostListener =
131 new InternalHostListener();
132 private final IntentListener intentListener =
133 new InternalIntentListener();
134 private final FlowRuleListener flowRuleListener =
135 new InternalFlowRuleListener();
Simon Hunt7092cc42016-04-06 18:40:17 -0700136
Madan Jampani492526a2016-06-06 17:24:04 -0700137 private ExecutorService eventHandler;
138
Simon Huntcda9c032016-04-11 10:32:54 -0700139
140 private ModelCache cache;
141
142
143 @Activate
144 protected void activate() {
Simon Hunt642bc452016-05-04 19:34:45 -0700145 cache = new ModelCache(new DefaultServiceBundle(), eventDispatcher);
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700146 eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui/topo", "event-handler", log));
Simon Huntcda9c032016-04-11 10:32:54 -0700147
148 eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
149
150 clusterService.addListener(clusterListener);
151 mastershipService.addListener(mastershipListener);
152 regionService.addListener(regionListener);
153 deviceService.addListener(deviceListener);
154 linkService.addListener(linkListener);
155 hostService.addListener(hostListener);
156 intentService.addListener(intentListener);
157 flowService.addListener(flowRuleListener);
158
159 cache.load();
160
161 log.info("Started");
Simon Hunted804d52016-03-30 09:51:40 -0700162 }
163
Simon Huntcda9c032016-04-11 10:32:54 -0700164 @Deactivate
165 protected void deactivate() {
166 eventDispatcher.removeSink(UiModelEvent.class);
167
168 clusterService.removeListener(clusterListener);
169 mastershipService.removeListener(mastershipListener);
170 regionService.removeListener(regionListener);
171 deviceService.removeListener(deviceListener);
172 linkService.removeListener(linkListener);
173 hostService.removeListener(hostListener);
174 intentService.removeListener(intentListener);
175 flowService.removeListener(flowRuleListener);
176
Madan Jampani492526a2016-06-06 17:24:04 -0700177 eventHandler.shutdown();
178
Simon Huntcda9c032016-04-11 10:32:54 -0700179 cache.clear();
180 cache = null;
181
182 log.info("Stopped");
183 }
184
185
Simon Huntf679c4e2016-04-01 17:02:24 -0700186 /**
187 * Registers a UI topology session with the topology model.
188 *
189 * @param session the session to register
190 */
191 public void register(UiTopoSession session) {
192 log.info("Registering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700193 addListener(session);
Simon Hunted804d52016-03-30 09:51:40 -0700194 }
195
Simon Huntf679c4e2016-04-01 17:02:24 -0700196 /**
197 * Unregisters a UI topology session from the topology model.
198 *
199 * @param session the session to unregister
200 */
201 public void unregister(UiTopoSession session) {
202 log.info("Unregistering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700203 removeListener(session);
Simon Huntf679c4e2016-04-01 17:02:24 -0700204 }
205
Simon Huntd5b96732016-07-08 13:22:27 -0700206
207 // =======================================================================
Simon Hunt10973dd2016-08-01 15:50:35 -0700208 // Methods for topo session (or CLI) to use to get information from us
Simon Huntd5b96732016-07-08 13:22:27 -0700209
210 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700211 * Refreshes the cache's internal state.
212 */
213 public void refresh() {
214 cache.refresh();
215 }
216
217 /**
218 * Returns the list of cluster members stored in the model cache.
Simon Huntd5b96732016-07-08 13:22:27 -0700219 *
220 * @return list of cluster members
221 */
222 public List<UiClusterMember> getClusterMembers() {
223 return cache.getAllClusterMembers();
224 }
225
Simon Huntd5b96732016-07-08 13:22:27 -0700226 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700227 * Returns the set of regions stored in the model cache.
Simon Hunt10973dd2016-08-01 15:50:35 -0700228 *
229 * @return set of regions
230 */
231 public Set<UiRegion> getRegions() {
232 return cache.getAllRegions();
233 }
234
235 /**
Simon Hunt977aa052016-07-20 17:08:29 -0700236 * Returns the region for the given identifier.
Simon Huntd5b96732016-07-08 13:22:27 -0700237 *
Simon Hunt977aa052016-07-20 17:08:29 -0700238 * @param id region identifier
239 * @return the region
Simon Huntd5b96732016-07-08 13:22:27 -0700240 */
Simon Hunt977aa052016-07-20 17:08:29 -0700241 public UiRegion getRegion(RegionId id) {
242 return cache.accessRegion(id);
Simon Huntd5b96732016-07-08 13:22:27 -0700243 }
244
Simon Huntb1ce2602016-07-23 14:04:31 -0700245 /**
246 * Returns the null region.
247 *
248 * @return the null region
249 */
250 public UiRegion getNullRegion() {
251 return cache.nullRegion();
252 }
253
254 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700255 * Returns the set of devices stored in the model cache.
256 *
257 * @return set of devices
Simon Huntb1ce2602016-07-23 14:04:31 -0700258 */
Simon Hunt4854f3d2016-08-02 18:13:15 -0700259 public Set<UiDevice> getDevices() {
260 return cache.getAllDevices();
261 }
262
263 /**
264 * Returns the set of hosts stored in the model cache.
265 *
266 * @return set of hosts
267 */
268 public Set<UiHost> getHosts() {
269 return cache.getAllHosts();
270 }
271
272 /**
Simon Huntc13082f2016-08-03 21:20:23 -0700273 * Returns the set of device links stored in the model cache.
Simon Hunt4854f3d2016-08-02 18:13:15 -0700274 *
Simon Huntc13082f2016-08-03 21:20:23 -0700275 * @return set of device links
Simon Hunt4854f3d2016-08-02 18:13:15 -0700276 */
Simon Huntc13082f2016-08-03 21:20:23 -0700277 public Set<UiDeviceLink> getDeviceLinks() {
278 return cache.getAllDeviceLinks();
279 }
280
281 /**
282 * Returns the synthetic links associated with the specified region.
283 *
284 * @param regionId region ID
285 * @return synthetic links for that region
286 */
287 public List<UiSynthLink> getSynthLinks(RegionId regionId) {
288 return cache.getSynthLinks(regionId);
Simon Huntb1ce2602016-07-23 14:04:31 -0700289 }
290
Simon Huntd5b96732016-07-08 13:22:27 -0700291 // =====================================================================
292
293
Simon Hunt642bc452016-05-04 19:34:45 -0700294 /**
295 * Default implementation of service bundle to return references to our
296 * dynamically injected services.
297 */
298 private class DefaultServiceBundle implements ServiceBundle {
299 @Override
Simon Hunt4f4ffc32016-08-03 18:30:47 -0700300 public UiTopoLayoutService layout() {
301 return layoutService;
302 }
303
304 @Override
Simon Hunt642bc452016-05-04 19:34:45 -0700305 public ClusterService cluster() {
306 return clusterService;
307 }
308
309 @Override
310 public MastershipService mastership() {
311 return mastershipService;
312 }
313
314 @Override
315 public RegionService region() {
316 return regionService;
317 }
318
319 @Override
320 public DeviceService device() {
321 return deviceService;
322 }
323
324 @Override
325 public LinkService link() {
326 return linkService;
327 }
328
329 @Override
330 public HostService host() {
331 return hostService;
332 }
333
334 @Override
335 public IntentService intent() {
336 return intentService;
337 }
338
339 @Override
340 public FlowRuleService flow() {
341 return flowService;
342 }
343 }
344
Simon Hunt7092cc42016-04-06 18:40:17 -0700345
Simon Huntcda9c032016-04-11 10:32:54 -0700346 private class InternalClusterListener implements ClusterEventListener {
347 @Override
348 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700349 eventHandler.execute(() -> handleEvent(event));
350 }
351
352 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700353 ControllerNode cnode = event.subject();
354
355 switch (event.type()) {
356
357 case INSTANCE_ADDED:
358 case INSTANCE_ACTIVATED:
359 case INSTANCE_READY:
360 case INSTANCE_DEACTIVATED:
361 cache.addOrUpdateClusterMember(cnode);
362 break;
363
364 case INSTANCE_REMOVED:
365 cache.removeClusterMember(cnode);
366 break;
367
368 default:
369 break;
370 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700371 }
Simon Huntcda9c032016-04-11 10:32:54 -0700372 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700373
Simon Huntcda9c032016-04-11 10:32:54 -0700374 private class InternalMastershipListener implements MastershipListener {
375 @Override
376 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700377 DeviceId deviceId = event.subject();
378 RoleInfo roleInfo = event.roleInfo();
379
380 switch (event.type()) {
381 case MASTER_CHANGED:
382 case BACKUPS_CHANGED:
383 cache.updateMasterships(deviceId, roleInfo);
384 break;
385
386 default:
387 break;
388 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700389 }
Simon Huntcda9c032016-04-11 10:32:54 -0700390 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700391
Simon Huntcda9c032016-04-11 10:32:54 -0700392 private class InternalRegionListener implements RegionListener {
393 @Override
394 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700395 Region region = event.subject();
396
397 switch (event.type()) {
398
399 case REGION_ADDED:
400 case REGION_UPDATED:
401 case REGION_MEMBERSHIP_CHANGED:
402 cache.addOrUpdateRegion(region);
403 break;
404
405 case REGION_REMOVED:
406 cache.removeRegion(region);
407 break;
408
409 default:
410 break;
411 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700412 }
Simon Huntcda9c032016-04-11 10:32:54 -0700413 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700414
Simon Huntcda9c032016-04-11 10:32:54 -0700415 private class InternalDeviceListener implements DeviceListener {
416 @Override
417 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700418 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700419
Simon Huntcda9c032016-04-11 10:32:54 -0700420 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700421
Simon Huntcda9c032016-04-11 10:32:54 -0700422 case DEVICE_ADDED:
423 case DEVICE_UPDATED:
424 case DEVICE_AVAILABILITY_CHANGED:
425 case DEVICE_SUSPENDED:
426 cache.addOrUpdateDevice(device);
427 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700428
Simon Huntcda9c032016-04-11 10:32:54 -0700429 case DEVICE_REMOVED:
430 cache.removeDevice(device);
431 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700432
Simon Huntcda9c032016-04-11 10:32:54 -0700433 default:
434 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700435 }
436 }
437 }
438
Simon Huntcda9c032016-04-11 10:32:54 -0700439 private class InternalLinkListener implements LinkListener {
440 @Override
441 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700442 Link link = event.subject();
443
444 switch (event.type()) {
445
446 case LINK_ADDED:
447 case LINK_UPDATED:
Simon Huntc13082f2016-08-03 21:20:23 -0700448 cache.addOrUpdateDeviceLink(link);
Simon Hunt23fb1352016-04-11 12:15:19 -0700449 break;
450
451 case LINK_REMOVED:
Simon Huntc13082f2016-08-03 21:20:23 -0700452 cache.removeDeviceLink(link);
Simon Hunt23fb1352016-04-11 12:15:19 -0700453 break;
454
455 default:
456 break;
457 }
Simon Huntcda9c032016-04-11 10:32:54 -0700458 }
Simon Hunted804d52016-03-30 09:51:40 -0700459 }
460
Simon Huntcda9c032016-04-11 10:32:54 -0700461 private class InternalHostListener implements HostListener {
462 @Override
463 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700464 Host host = event.subject();
465 Host prevHost = event.prevSubject();
466
467 switch (event.type()) {
468
469 case HOST_ADDED:
470 case HOST_UPDATED:
471 cache.addOrUpdateHost(host);
472 break;
473
474 case HOST_MOVED:
475 cache.moveHost(host, prevHost);
476 break;
477
478 case HOST_REMOVED:
479 cache.removeHost(host);
480 break;
481
482 default:
483 break;
484 }
Simon Huntcda9c032016-04-11 10:32:54 -0700485 }
Simon Hunted804d52016-03-30 09:51:40 -0700486 }
Simon Huntcda9c032016-04-11 10:32:54 -0700487
Simon Hunt23fb1352016-04-11 12:15:19 -0700488 // =======================================================================
489 // NOTE: Neither intents nor flows are modeled by the UiTopology.
490 // Rather, they are serviced directly from this class.
491 // Additionally, since we are only retrieving counts (in the current
492 // implementation), we'll fetch them on demand from the service.
493 // Thus, the following internal listeners are stubs only (for now).
494 // =======================================================================
495
Simon Huntcda9c032016-04-11 10:32:54 -0700496 private class InternalIntentListener implements IntentListener {
497 @Override
498 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700499 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700500 }
501 }
502
503 private class InternalFlowRuleListener implements FlowRuleListener {
504 @Override
505 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700506 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700507 }
508 }
509
Simon Hunted804d52016-03-30 09:51:40 -0700510}