blob: 52eea69c30732c7f4d89ea4d512a8b3028380224 [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 Huntf679c4e2016-04-01 17:02:24 -070063import org.onosproject.ui.impl.topo.UiTopoSession;
Simon Hunt642bc452016-05-04 19:34:45 -070064import org.onosproject.ui.model.ServiceBundle;
Simon Huntd5b96732016-07-08 13:22:27 -070065import org.onosproject.ui.model.topo.UiClusterMember;
Simon Huntd5b96732016-07-08 13:22:27 -070066import org.onosproject.ui.model.topo.UiRegion;
Simon Hunted804d52016-03-30 09:51:40 -070067import org.slf4j.Logger;
68import org.slf4j.LoggerFactory;
69
Simon Huntd5b96732016-07-08 13:22:27 -070070import java.util.List;
Simon Hunt10973dd2016-08-01 15:50:35 -070071import java.util.Set;
Simon Huntd5b96732016-07-08 13:22:27 -070072import java.util.concurrent.ExecutorService;
73import java.util.concurrent.Executors;
74
Simon Hunted804d52016-03-30 09:51:40 -070075/**
Simon Huntcda9c032016-04-11 10:32:54 -070076 * Service that creates and maintains the UI-model of the network topology.
Simon Hunted804d52016-03-30 09:51:40 -070077 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070078@Component(immediate = true, enabled = true)
Simon Huntcda9c032016-04-11 10:32:54 -070079@Service(value = UiSharedTopologyModel.class)
80public final class UiSharedTopologyModel
81 extends AbstractListenerManager<UiModelEvent, UiModelListener> {
Simon Hunted804d52016-03-30 09:51:40 -070082
83 private static final Logger log =
84 LoggerFactory.getLogger(UiSharedTopologyModel.class);
85
Simon Huntcda9c032016-04-11 10:32:54 -070086 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 private ClusterService clusterService;
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 private MastershipService mastershipService;
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 private RegionService regionService;
92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 private DeviceService deviceService;
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 private LinkService linkService;
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 private HostService hostService;
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 private IntentService intentService;
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 private FlowRuleService flowService;
Simon Hunt7092cc42016-04-06 18:40:17 -0700102
Simon Huntcda9c032016-04-11 10:32:54 -0700103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 private StatisticService flowStatsService;
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 private PortStatisticsService portStatsService;
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
108 private TopologyService topologyService;
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 private TunnelService tunnelService;
Simon Hunted804d52016-03-30 09:51:40 -0700111
Simon Huntcda9c032016-04-11 10:32:54 -0700112 private final ClusterEventListener clusterListener =
113 new InternalClusterListener();
114 private final MastershipListener mastershipListener =
115 new InternalMastershipListener();
116 private final RegionListener regionListener =
117 new InternalRegionListener();
118 private final DeviceListener deviceListener =
119 new InternalDeviceListener();
120 private final LinkListener linkListener =
121 new InternalLinkListener();
122 private final HostListener hostListener =
123 new InternalHostListener();
124 private final IntentListener intentListener =
125 new InternalIntentListener();
126 private final FlowRuleListener flowRuleListener =
127 new InternalFlowRuleListener();
Simon Hunt7092cc42016-04-06 18:40:17 -0700128
Madan Jampani492526a2016-06-06 17:24:04 -0700129 private ExecutorService eventHandler;
130
Simon Huntcda9c032016-04-11 10:32:54 -0700131
132 private ModelCache cache;
133
134
135 @Activate
136 protected void activate() {
Simon Hunt642bc452016-05-04 19:34:45 -0700137 cache = new ModelCache(new DefaultServiceBundle(), eventDispatcher);
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700138 eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui/topo", "event-handler", log));
Simon Huntcda9c032016-04-11 10:32:54 -0700139
140 eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
141
142 clusterService.addListener(clusterListener);
143 mastershipService.addListener(mastershipListener);
144 regionService.addListener(regionListener);
145 deviceService.addListener(deviceListener);
146 linkService.addListener(linkListener);
147 hostService.addListener(hostListener);
148 intentService.addListener(intentListener);
149 flowService.addListener(flowRuleListener);
150
151 cache.load();
152
153 log.info("Started");
Simon Hunted804d52016-03-30 09:51:40 -0700154 }
155
Simon Huntcda9c032016-04-11 10:32:54 -0700156 @Deactivate
157 protected void deactivate() {
158 eventDispatcher.removeSink(UiModelEvent.class);
159
160 clusterService.removeListener(clusterListener);
161 mastershipService.removeListener(mastershipListener);
162 regionService.removeListener(regionListener);
163 deviceService.removeListener(deviceListener);
164 linkService.removeListener(linkListener);
165 hostService.removeListener(hostListener);
166 intentService.removeListener(intentListener);
167 flowService.removeListener(flowRuleListener);
168
Madan Jampani492526a2016-06-06 17:24:04 -0700169 eventHandler.shutdown();
170
Simon Huntcda9c032016-04-11 10:32:54 -0700171 cache.clear();
172 cache = null;
173
174 log.info("Stopped");
175 }
176
177
Simon Huntf679c4e2016-04-01 17:02:24 -0700178 /**
179 * Registers a UI topology session with the topology model.
180 *
181 * @param session the session to register
182 */
183 public void register(UiTopoSession session) {
184 log.info("Registering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700185 addListener(session);
Simon Hunted804d52016-03-30 09:51:40 -0700186 }
187
Simon Huntf679c4e2016-04-01 17:02:24 -0700188 /**
189 * Unregisters a UI topology session from the topology model.
190 *
191 * @param session the session to unregister
192 */
193 public void unregister(UiTopoSession session) {
194 log.info("Unregistering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700195 removeListener(session);
Simon Huntf679c4e2016-04-01 17:02:24 -0700196 }
197
Simon Huntd5b96732016-07-08 13:22:27 -0700198
199 // =======================================================================
Simon Hunt10973dd2016-08-01 15:50:35 -0700200 // Methods for topo session (or CLI) to use to get information from us
Simon Huntd5b96732016-07-08 13:22:27 -0700201
202 /**
203 * Returns the list of cluster members stored in our model cache.
204 *
205 * @return list of cluster members
206 */
207 public List<UiClusterMember> getClusterMembers() {
208 return cache.getAllClusterMembers();
209 }
210
Simon Huntd5b96732016-07-08 13:22:27 -0700211 /**
Simon Hunt10973dd2016-08-01 15:50:35 -0700212 * Returns the set of regions stored in our model cache.
213 *
214 * @return set of regions
215 */
216 public Set<UiRegion> getRegions() {
217 return cache.getAllRegions();
218 }
219
220 /**
Simon Hunt977aa052016-07-20 17:08:29 -0700221 * Returns the region for the given identifier.
Simon Huntd5b96732016-07-08 13:22:27 -0700222 *
Simon Hunt977aa052016-07-20 17:08:29 -0700223 * @param id region identifier
224 * @return the region
Simon Huntd5b96732016-07-08 13:22:27 -0700225 */
Simon Hunt977aa052016-07-20 17:08:29 -0700226 public UiRegion getRegion(RegionId id) {
227 return cache.accessRegion(id);
Simon Huntd5b96732016-07-08 13:22:27 -0700228 }
229
Simon Huntb1ce2602016-07-23 14:04:31 -0700230 /**
231 * Returns the null region.
232 *
233 * @return the null region
234 */
235 public UiRegion getNullRegion() {
236 return cache.nullRegion();
237 }
238
239 /**
240 * Refreshes the cache's internal state.
241 */
242 public void refresh() {
243 cache.refresh();
244 }
245
Simon Huntd5b96732016-07-08 13:22:27 -0700246 // =====================================================================
247
248
Simon Hunt642bc452016-05-04 19:34:45 -0700249 /**
250 * Default implementation of service bundle to return references to our
251 * dynamically injected services.
252 */
253 private class DefaultServiceBundle implements ServiceBundle {
254 @Override
255 public ClusterService cluster() {
256 return clusterService;
257 }
258
259 @Override
260 public MastershipService mastership() {
261 return mastershipService;
262 }
263
264 @Override
265 public RegionService region() {
266 return regionService;
267 }
268
269 @Override
270 public DeviceService device() {
271 return deviceService;
272 }
273
274 @Override
275 public LinkService link() {
276 return linkService;
277 }
278
279 @Override
280 public HostService host() {
281 return hostService;
282 }
283
284 @Override
285 public IntentService intent() {
286 return intentService;
287 }
288
289 @Override
290 public FlowRuleService flow() {
291 return flowService;
292 }
293 }
294
Simon Hunt7092cc42016-04-06 18:40:17 -0700295
Simon Huntcda9c032016-04-11 10:32:54 -0700296 private class InternalClusterListener implements ClusterEventListener {
297 @Override
298 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700299 eventHandler.execute(() -> handleEvent(event));
300 }
301
302 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700303 ControllerNode cnode = event.subject();
304
305 switch (event.type()) {
306
307 case INSTANCE_ADDED:
308 case INSTANCE_ACTIVATED:
309 case INSTANCE_READY:
310 case INSTANCE_DEACTIVATED:
311 cache.addOrUpdateClusterMember(cnode);
312 break;
313
314 case INSTANCE_REMOVED:
315 cache.removeClusterMember(cnode);
316 break;
317
318 default:
319 break;
320 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700321 }
Simon Huntcda9c032016-04-11 10:32:54 -0700322 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700323
Simon Huntcda9c032016-04-11 10:32:54 -0700324 private class InternalMastershipListener implements MastershipListener {
325 @Override
326 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700327 DeviceId deviceId = event.subject();
328 RoleInfo roleInfo = event.roleInfo();
329
330 switch (event.type()) {
331 case MASTER_CHANGED:
332 case BACKUPS_CHANGED:
333 cache.updateMasterships(deviceId, roleInfo);
334 break;
335
336 default:
337 break;
338 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700339 }
Simon Huntcda9c032016-04-11 10:32:54 -0700340 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700341
Simon Huntcda9c032016-04-11 10:32:54 -0700342 private class InternalRegionListener implements RegionListener {
343 @Override
344 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700345 Region region = event.subject();
346
347 switch (event.type()) {
348
349 case REGION_ADDED:
350 case REGION_UPDATED:
351 case REGION_MEMBERSHIP_CHANGED:
352 cache.addOrUpdateRegion(region);
353 break;
354
355 case REGION_REMOVED:
356 cache.removeRegion(region);
357 break;
358
359 default:
360 break;
361 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700362 }
Simon Huntcda9c032016-04-11 10:32:54 -0700363 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700364
Simon Huntcda9c032016-04-11 10:32:54 -0700365 private class InternalDeviceListener implements DeviceListener {
366 @Override
367 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700368 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700369
Simon Huntcda9c032016-04-11 10:32:54 -0700370 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700371
Simon Huntcda9c032016-04-11 10:32:54 -0700372 case DEVICE_ADDED:
373 case DEVICE_UPDATED:
374 case DEVICE_AVAILABILITY_CHANGED:
375 case DEVICE_SUSPENDED:
376 cache.addOrUpdateDevice(device);
377 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700378
Simon Huntcda9c032016-04-11 10:32:54 -0700379 case DEVICE_REMOVED:
380 cache.removeDevice(device);
381 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700382
Simon Huntcda9c032016-04-11 10:32:54 -0700383 default:
384 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700385 }
386 }
387 }
388
Simon Huntcda9c032016-04-11 10:32:54 -0700389 private class InternalLinkListener implements LinkListener {
390 @Override
391 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700392 Link link = event.subject();
393
394 switch (event.type()) {
395
396 case LINK_ADDED:
397 case LINK_UPDATED:
398 cache.addOrUpdateLink(link);
399 break;
400
401 case LINK_REMOVED:
402 cache.removeLink(link);
403 break;
404
405 default:
406 break;
407 }
Simon Huntcda9c032016-04-11 10:32:54 -0700408 }
Simon Hunted804d52016-03-30 09:51:40 -0700409 }
410
Simon Huntcda9c032016-04-11 10:32:54 -0700411 private class InternalHostListener implements HostListener {
412 @Override
413 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700414 Host host = event.subject();
415 Host prevHost = event.prevSubject();
416
417 switch (event.type()) {
418
419 case HOST_ADDED:
420 case HOST_UPDATED:
421 cache.addOrUpdateHost(host);
422 break;
423
424 case HOST_MOVED:
425 cache.moveHost(host, prevHost);
426 break;
427
428 case HOST_REMOVED:
429 cache.removeHost(host);
430 break;
431
432 default:
433 break;
434 }
Simon Huntcda9c032016-04-11 10:32:54 -0700435 }
Simon Hunted804d52016-03-30 09:51:40 -0700436 }
Simon Huntcda9c032016-04-11 10:32:54 -0700437
Simon Hunt23fb1352016-04-11 12:15:19 -0700438 // =======================================================================
439 // NOTE: Neither intents nor flows are modeled by the UiTopology.
440 // Rather, they are serviced directly from this class.
441 // Additionally, since we are only retrieving counts (in the current
442 // implementation), we'll fetch them on demand from the service.
443 // Thus, the following internal listeners are stubs only (for now).
444 // =======================================================================
445
Simon Huntcda9c032016-04-11 10:32:54 -0700446 private class InternalIntentListener implements IntentListener {
447 @Override
448 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700449 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700450 }
451 }
452
453 private class InternalFlowRuleListener implements FlowRuleListener {
454 @Override
455 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700456 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700457 }
458 }
459
Simon Hunted804d52016-03-30 09:51:40 -0700460}