blob: a12e34d33271cc240c8cd6e646786f9b2184b0d0 [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;
68import org.onosproject.ui.model.topo.UiHost;
69import org.onosproject.ui.model.topo.UiLink;
Simon Huntd5b96732016-07-08 13:22:27 -070070import org.onosproject.ui.model.topo.UiRegion;
Simon Hunted804d52016-03-30 09:51:40 -070071import org.slf4j.Logger;
72import org.slf4j.LoggerFactory;
73
Simon Huntd5b96732016-07-08 13:22:27 -070074import java.util.List;
Simon Hunt10973dd2016-08-01 15:50:35 -070075import java.util.Set;
Simon Huntd5b96732016-07-08 13:22:27 -070076import java.util.concurrent.ExecutorService;
77import java.util.concurrent.Executors;
78
Simon Hunted804d52016-03-30 09:51:40 -070079/**
Simon Huntcda9c032016-04-11 10:32:54 -070080 * Service that creates and maintains the UI-model of the network topology.
Simon Hunted804d52016-03-30 09:51:40 -070081 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070082@Component(immediate = true, enabled = true)
Simon Huntcda9c032016-04-11 10:32:54 -070083@Service(value = UiSharedTopologyModel.class)
84public final class UiSharedTopologyModel
85 extends AbstractListenerManager<UiModelEvent, UiModelListener> {
Simon Hunted804d52016-03-30 09:51:40 -070086
87 private static final Logger log =
88 LoggerFactory.getLogger(UiSharedTopologyModel.class);
89
Simon Huntcda9c032016-04-11 10:32:54 -070090 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Simon Hunt4f4ffc32016-08-03 18:30:47 -070091 private UiTopoLayoutService layoutService;
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Simon Huntcda9c032016-04-11 10:32:54 -070094 private ClusterService clusterService;
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 private MastershipService mastershipService;
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 private RegionService regionService;
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 private DeviceService deviceService;
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 private LinkService linkService;
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 private HostService hostService;
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 private IntentService intentService;
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
108 private FlowRuleService flowService;
Simon Hunt7092cc42016-04-06 18:40:17 -0700109
Simon Huntcda9c032016-04-11 10:32:54 -0700110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 private StatisticService flowStatsService;
112 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
113 private PortStatisticsService portStatsService;
114 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
115 private TopologyService topologyService;
116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 private TunnelService tunnelService;
Simon Hunted804d52016-03-30 09:51:40 -0700118
Simon Huntcda9c032016-04-11 10:32:54 -0700119 private final ClusterEventListener clusterListener =
120 new InternalClusterListener();
121 private final MastershipListener mastershipListener =
122 new InternalMastershipListener();
123 private final RegionListener regionListener =
124 new InternalRegionListener();
125 private final DeviceListener deviceListener =
126 new InternalDeviceListener();
127 private final LinkListener linkListener =
128 new InternalLinkListener();
129 private final HostListener hostListener =
130 new InternalHostListener();
131 private final IntentListener intentListener =
132 new InternalIntentListener();
133 private final FlowRuleListener flowRuleListener =
134 new InternalFlowRuleListener();
Simon Hunt7092cc42016-04-06 18:40:17 -0700135
Madan Jampani492526a2016-06-06 17:24:04 -0700136 private ExecutorService eventHandler;
137
Simon Huntcda9c032016-04-11 10:32:54 -0700138
139 private ModelCache cache;
140
141
142 @Activate
143 protected void activate() {
Simon Hunt642bc452016-05-04 19:34:45 -0700144 cache = new ModelCache(new DefaultServiceBundle(), eventDispatcher);
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700145 eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui/topo", "event-handler", log));
Simon Huntcda9c032016-04-11 10:32:54 -0700146
147 eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
148
149 clusterService.addListener(clusterListener);
150 mastershipService.addListener(mastershipListener);
151 regionService.addListener(regionListener);
152 deviceService.addListener(deviceListener);
153 linkService.addListener(linkListener);
154 hostService.addListener(hostListener);
155 intentService.addListener(intentListener);
156 flowService.addListener(flowRuleListener);
157
158 cache.load();
159
160 log.info("Started");
Simon Hunted804d52016-03-30 09:51:40 -0700161 }
162
Simon Huntcda9c032016-04-11 10:32:54 -0700163 @Deactivate
164 protected void deactivate() {
165 eventDispatcher.removeSink(UiModelEvent.class);
166
167 clusterService.removeListener(clusterListener);
168 mastershipService.removeListener(mastershipListener);
169 regionService.removeListener(regionListener);
170 deviceService.removeListener(deviceListener);
171 linkService.removeListener(linkListener);
172 hostService.removeListener(hostListener);
173 intentService.removeListener(intentListener);
174 flowService.removeListener(flowRuleListener);
175
Madan Jampani492526a2016-06-06 17:24:04 -0700176 eventHandler.shutdown();
177
Simon Huntcda9c032016-04-11 10:32:54 -0700178 cache.clear();
179 cache = null;
180
181 log.info("Stopped");
182 }
183
184
Simon Huntf679c4e2016-04-01 17:02:24 -0700185 /**
186 * Registers a UI topology session with the topology model.
187 *
188 * @param session the session to register
189 */
190 public void register(UiTopoSession session) {
191 log.info("Registering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700192 addListener(session);
Simon Hunted804d52016-03-30 09:51:40 -0700193 }
194
Simon Huntf679c4e2016-04-01 17:02:24 -0700195 /**
196 * Unregisters a UI topology session from the topology model.
197 *
198 * @param session the session to unregister
199 */
200 public void unregister(UiTopoSession session) {
201 log.info("Unregistering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700202 removeListener(session);
Simon Huntf679c4e2016-04-01 17:02:24 -0700203 }
204
Simon Huntd5b96732016-07-08 13:22:27 -0700205
206 // =======================================================================
Simon Hunt10973dd2016-08-01 15:50:35 -0700207 // Methods for topo session (or CLI) to use to get information from us
Simon Huntd5b96732016-07-08 13:22:27 -0700208
209 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700210 * Refreshes the cache's internal state.
211 */
212 public void refresh() {
213 cache.refresh();
214 }
215
216 /**
217 * Returns the list of cluster members stored in the model cache.
Simon Huntd5b96732016-07-08 13:22:27 -0700218 *
219 * @return list of cluster members
220 */
221 public List<UiClusterMember> getClusterMembers() {
222 return cache.getAllClusterMembers();
223 }
224
Simon Huntd5b96732016-07-08 13:22:27 -0700225 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700226 * Returns the set of regions stored in the model cache.
Simon Hunt10973dd2016-08-01 15:50:35 -0700227 *
228 * @return set of regions
229 */
230 public Set<UiRegion> getRegions() {
231 return cache.getAllRegions();
232 }
233
234 /**
Simon Hunt977aa052016-07-20 17:08:29 -0700235 * Returns the region for the given identifier.
Simon Huntd5b96732016-07-08 13:22:27 -0700236 *
Simon Hunt977aa052016-07-20 17:08:29 -0700237 * @param id region identifier
238 * @return the region
Simon Huntd5b96732016-07-08 13:22:27 -0700239 */
Simon Hunt977aa052016-07-20 17:08:29 -0700240 public UiRegion getRegion(RegionId id) {
241 return cache.accessRegion(id);
Simon Huntd5b96732016-07-08 13:22:27 -0700242 }
243
Simon Huntb1ce2602016-07-23 14:04:31 -0700244 /**
245 * Returns the null region.
246 *
247 * @return the null region
248 */
249 public UiRegion getNullRegion() {
250 return cache.nullRegion();
251 }
252
253 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700254 * Returns the set of devices stored in the model cache.
255 *
256 * @return set of devices
Simon Huntb1ce2602016-07-23 14:04:31 -0700257 */
Simon Hunt4854f3d2016-08-02 18:13:15 -0700258 public Set<UiDevice> getDevices() {
259 return cache.getAllDevices();
260 }
261
262 /**
263 * Returns the set of hosts stored in the model cache.
264 *
265 * @return set of hosts
266 */
267 public Set<UiHost> getHosts() {
268 return cache.getAllHosts();
269 }
270
271 /**
272 * Returns the set of links stored in the model cache.
273 *
274 * @return set of links
275 */
276 public Set<UiLink> getLinks() {
277 return cache.getAllLinks();
Simon Huntb1ce2602016-07-23 14:04:31 -0700278 }
279
Simon Huntd5b96732016-07-08 13:22:27 -0700280 // =====================================================================
281
282
Simon Hunt642bc452016-05-04 19:34:45 -0700283 /**
284 * Default implementation of service bundle to return references to our
285 * dynamically injected services.
286 */
287 private class DefaultServiceBundle implements ServiceBundle {
288 @Override
Simon Hunt4f4ffc32016-08-03 18:30:47 -0700289 public UiTopoLayoutService layout() {
290 return layoutService;
291 }
292
293 @Override
Simon Hunt642bc452016-05-04 19:34:45 -0700294 public ClusterService cluster() {
295 return clusterService;
296 }
297
298 @Override
299 public MastershipService mastership() {
300 return mastershipService;
301 }
302
303 @Override
304 public RegionService region() {
305 return regionService;
306 }
307
308 @Override
309 public DeviceService device() {
310 return deviceService;
311 }
312
313 @Override
314 public LinkService link() {
315 return linkService;
316 }
317
318 @Override
319 public HostService host() {
320 return hostService;
321 }
322
323 @Override
324 public IntentService intent() {
325 return intentService;
326 }
327
328 @Override
329 public FlowRuleService flow() {
330 return flowService;
331 }
332 }
333
Simon Hunt7092cc42016-04-06 18:40:17 -0700334
Simon Huntcda9c032016-04-11 10:32:54 -0700335 private class InternalClusterListener implements ClusterEventListener {
336 @Override
337 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700338 eventHandler.execute(() -> handleEvent(event));
339 }
340
341 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700342 ControllerNode cnode = event.subject();
343
344 switch (event.type()) {
345
346 case INSTANCE_ADDED:
347 case INSTANCE_ACTIVATED:
348 case INSTANCE_READY:
349 case INSTANCE_DEACTIVATED:
350 cache.addOrUpdateClusterMember(cnode);
351 break;
352
353 case INSTANCE_REMOVED:
354 cache.removeClusterMember(cnode);
355 break;
356
357 default:
358 break;
359 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700360 }
Simon Huntcda9c032016-04-11 10:32:54 -0700361 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700362
Simon Huntcda9c032016-04-11 10:32:54 -0700363 private class InternalMastershipListener implements MastershipListener {
364 @Override
365 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700366 DeviceId deviceId = event.subject();
367 RoleInfo roleInfo = event.roleInfo();
368
369 switch (event.type()) {
370 case MASTER_CHANGED:
371 case BACKUPS_CHANGED:
372 cache.updateMasterships(deviceId, roleInfo);
373 break;
374
375 default:
376 break;
377 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700378 }
Simon Huntcda9c032016-04-11 10:32:54 -0700379 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700380
Simon Huntcda9c032016-04-11 10:32:54 -0700381 private class InternalRegionListener implements RegionListener {
382 @Override
383 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700384 Region region = event.subject();
385
386 switch (event.type()) {
387
388 case REGION_ADDED:
389 case REGION_UPDATED:
390 case REGION_MEMBERSHIP_CHANGED:
391 cache.addOrUpdateRegion(region);
392 break;
393
394 case REGION_REMOVED:
395 cache.removeRegion(region);
396 break;
397
398 default:
399 break;
400 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700401 }
Simon Huntcda9c032016-04-11 10:32:54 -0700402 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700403
Simon Huntcda9c032016-04-11 10:32:54 -0700404 private class InternalDeviceListener implements DeviceListener {
405 @Override
406 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700407 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700408
Simon Huntcda9c032016-04-11 10:32:54 -0700409 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700410
Simon Huntcda9c032016-04-11 10:32:54 -0700411 case DEVICE_ADDED:
412 case DEVICE_UPDATED:
413 case DEVICE_AVAILABILITY_CHANGED:
414 case DEVICE_SUSPENDED:
415 cache.addOrUpdateDevice(device);
416 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700417
Simon Huntcda9c032016-04-11 10:32:54 -0700418 case DEVICE_REMOVED:
419 cache.removeDevice(device);
420 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700421
Simon Huntcda9c032016-04-11 10:32:54 -0700422 default:
423 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700424 }
425 }
426 }
427
Simon Huntcda9c032016-04-11 10:32:54 -0700428 private class InternalLinkListener implements LinkListener {
429 @Override
430 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700431 Link link = event.subject();
432
433 switch (event.type()) {
434
435 case LINK_ADDED:
436 case LINK_UPDATED:
437 cache.addOrUpdateLink(link);
438 break;
439
440 case LINK_REMOVED:
441 cache.removeLink(link);
442 break;
443
444 default:
445 break;
446 }
Simon Huntcda9c032016-04-11 10:32:54 -0700447 }
Simon Hunted804d52016-03-30 09:51:40 -0700448 }
449
Simon Huntcda9c032016-04-11 10:32:54 -0700450 private class InternalHostListener implements HostListener {
451 @Override
452 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700453 Host host = event.subject();
454 Host prevHost = event.prevSubject();
455
456 switch (event.type()) {
457
458 case HOST_ADDED:
459 case HOST_UPDATED:
460 cache.addOrUpdateHost(host);
461 break;
462
463 case HOST_MOVED:
464 cache.moveHost(host, prevHost);
465 break;
466
467 case HOST_REMOVED:
468 cache.removeHost(host);
469 break;
470
471 default:
472 break;
473 }
Simon Huntcda9c032016-04-11 10:32:54 -0700474 }
Simon Hunted804d52016-03-30 09:51:40 -0700475 }
Simon Huntcda9c032016-04-11 10:32:54 -0700476
Simon Hunt23fb1352016-04-11 12:15:19 -0700477 // =======================================================================
478 // NOTE: Neither intents nor flows are modeled by the UiTopology.
479 // Rather, they are serviced directly from this class.
480 // Additionally, since we are only retrieving counts (in the current
481 // implementation), we'll fetch them on demand from the service.
482 // Thus, the following internal listeners are stubs only (for now).
483 // =======================================================================
484
Simon Huntcda9c032016-04-11 10:32:54 -0700485 private class InternalIntentListener implements IntentListener {
486 @Override
487 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700488 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700489 }
490 }
491
492 private class InternalFlowRuleListener implements FlowRuleListener {
493 @Override
494 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700495 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700496 }
497 }
498
Simon Hunted804d52016-03-30 09:51:40 -0700499}