blob: 4a5cc91bf8726c6c01a87699a928c45c8cd2f920 [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 Hunt4854f3d2016-08-02 18:13:15 -070066import org.onosproject.ui.model.topo.UiDevice;
67import org.onosproject.ui.model.topo.UiHost;
68import org.onosproject.ui.model.topo.UiLink;
Simon Huntd5b96732016-07-08 13:22:27 -070069import org.onosproject.ui.model.topo.UiRegion;
Simon Hunted804d52016-03-30 09:51:40 -070070import org.slf4j.Logger;
71import org.slf4j.LoggerFactory;
72
Simon Huntd5b96732016-07-08 13:22:27 -070073import java.util.List;
Simon Hunt10973dd2016-08-01 15:50:35 -070074import java.util.Set;
Simon Huntd5b96732016-07-08 13:22:27 -070075import java.util.concurrent.ExecutorService;
76import java.util.concurrent.Executors;
77
Simon Hunted804d52016-03-30 09:51:40 -070078/**
Simon Huntcda9c032016-04-11 10:32:54 -070079 * Service that creates and maintains the UI-model of the network topology.
Simon Hunted804d52016-03-30 09:51:40 -070080 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070081@Component(immediate = true, enabled = true)
Simon Huntcda9c032016-04-11 10:32:54 -070082@Service(value = UiSharedTopologyModel.class)
83public final class UiSharedTopologyModel
84 extends AbstractListenerManager<UiModelEvent, UiModelListener> {
Simon Hunted804d52016-03-30 09:51:40 -070085
86 private static final Logger log =
87 LoggerFactory.getLogger(UiSharedTopologyModel.class);
88
Simon Huntcda9c032016-04-11 10:32:54 -070089 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 private ClusterService clusterService;
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 private MastershipService mastershipService;
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 private RegionService regionService;
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 private DeviceService deviceService;
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 private LinkService linkService;
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 private HostService hostService;
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 private IntentService intentService;
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 private FlowRuleService flowService;
Simon Hunt7092cc42016-04-06 18:40:17 -0700105
Simon Huntcda9c032016-04-11 10:32:54 -0700106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 private StatisticService flowStatsService;
108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 private PortStatisticsService portStatsService;
110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 private TopologyService topologyService;
112 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
113 private TunnelService tunnelService;
Simon Hunted804d52016-03-30 09:51:40 -0700114
Simon Huntcda9c032016-04-11 10:32:54 -0700115 private final ClusterEventListener clusterListener =
116 new InternalClusterListener();
117 private final MastershipListener mastershipListener =
118 new InternalMastershipListener();
119 private final RegionListener regionListener =
120 new InternalRegionListener();
121 private final DeviceListener deviceListener =
122 new InternalDeviceListener();
123 private final LinkListener linkListener =
124 new InternalLinkListener();
125 private final HostListener hostListener =
126 new InternalHostListener();
127 private final IntentListener intentListener =
128 new InternalIntentListener();
129 private final FlowRuleListener flowRuleListener =
130 new InternalFlowRuleListener();
Simon Hunt7092cc42016-04-06 18:40:17 -0700131
Madan Jampani492526a2016-06-06 17:24:04 -0700132 private ExecutorService eventHandler;
133
Simon Huntcda9c032016-04-11 10:32:54 -0700134
135 private ModelCache cache;
136
137
138 @Activate
139 protected void activate() {
Simon Hunt642bc452016-05-04 19:34:45 -0700140 cache = new ModelCache(new DefaultServiceBundle(), eventDispatcher);
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700141 eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui/topo", "event-handler", log));
Simon Huntcda9c032016-04-11 10:32:54 -0700142
143 eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
144
145 clusterService.addListener(clusterListener);
146 mastershipService.addListener(mastershipListener);
147 regionService.addListener(regionListener);
148 deviceService.addListener(deviceListener);
149 linkService.addListener(linkListener);
150 hostService.addListener(hostListener);
151 intentService.addListener(intentListener);
152 flowService.addListener(flowRuleListener);
153
154 cache.load();
155
156 log.info("Started");
Simon Hunted804d52016-03-30 09:51:40 -0700157 }
158
Simon Huntcda9c032016-04-11 10:32:54 -0700159 @Deactivate
160 protected void deactivate() {
161 eventDispatcher.removeSink(UiModelEvent.class);
162
163 clusterService.removeListener(clusterListener);
164 mastershipService.removeListener(mastershipListener);
165 regionService.removeListener(regionListener);
166 deviceService.removeListener(deviceListener);
167 linkService.removeListener(linkListener);
168 hostService.removeListener(hostListener);
169 intentService.removeListener(intentListener);
170 flowService.removeListener(flowRuleListener);
171
Madan Jampani492526a2016-06-06 17:24:04 -0700172 eventHandler.shutdown();
173
Simon Huntcda9c032016-04-11 10:32:54 -0700174 cache.clear();
175 cache = null;
176
177 log.info("Stopped");
178 }
179
180
Simon Huntf679c4e2016-04-01 17:02:24 -0700181 /**
182 * Registers a UI topology session with the topology model.
183 *
184 * @param session the session to register
185 */
186 public void register(UiTopoSession session) {
187 log.info("Registering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700188 addListener(session);
Simon Hunted804d52016-03-30 09:51:40 -0700189 }
190
Simon Huntf679c4e2016-04-01 17:02:24 -0700191 /**
192 * Unregisters a UI topology session from the topology model.
193 *
194 * @param session the session to unregister
195 */
196 public void unregister(UiTopoSession session) {
197 log.info("Unregistering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700198 removeListener(session);
Simon Huntf679c4e2016-04-01 17:02:24 -0700199 }
200
Simon Huntd5b96732016-07-08 13:22:27 -0700201
202 // =======================================================================
Simon Hunt10973dd2016-08-01 15:50:35 -0700203 // Methods for topo session (or CLI) to use to get information from us
Simon Huntd5b96732016-07-08 13:22:27 -0700204
205 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700206 * Refreshes the cache's internal state.
207 */
208 public void refresh() {
209 cache.refresh();
210 }
211
212 /**
213 * Returns the list of cluster members stored in the model cache.
Simon Huntd5b96732016-07-08 13:22:27 -0700214 *
215 * @return list of cluster members
216 */
217 public List<UiClusterMember> getClusterMembers() {
218 return cache.getAllClusterMembers();
219 }
220
Simon Huntd5b96732016-07-08 13:22:27 -0700221 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700222 * Returns the set of regions stored in the model cache.
Simon Hunt10973dd2016-08-01 15:50:35 -0700223 *
224 * @return set of regions
225 */
226 public Set<UiRegion> getRegions() {
227 return cache.getAllRegions();
228 }
229
230 /**
Simon Hunt977aa052016-07-20 17:08:29 -0700231 * Returns the region for the given identifier.
Simon Huntd5b96732016-07-08 13:22:27 -0700232 *
Simon Hunt977aa052016-07-20 17:08:29 -0700233 * @param id region identifier
234 * @return the region
Simon Huntd5b96732016-07-08 13:22:27 -0700235 */
Simon Hunt977aa052016-07-20 17:08:29 -0700236 public UiRegion getRegion(RegionId id) {
237 return cache.accessRegion(id);
Simon Huntd5b96732016-07-08 13:22:27 -0700238 }
239
Simon Huntb1ce2602016-07-23 14:04:31 -0700240 /**
241 * Returns the null region.
242 *
243 * @return the null region
244 */
245 public UiRegion getNullRegion() {
246 return cache.nullRegion();
247 }
248
249 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700250 * Returns the set of devices stored in the model cache.
251 *
252 * @return set of devices
Simon Huntb1ce2602016-07-23 14:04:31 -0700253 */
Simon Hunt4854f3d2016-08-02 18:13:15 -0700254 public Set<UiDevice> getDevices() {
255 return cache.getAllDevices();
256 }
257
258 /**
259 * Returns the set of hosts stored in the model cache.
260 *
261 * @return set of hosts
262 */
263 public Set<UiHost> getHosts() {
264 return cache.getAllHosts();
265 }
266
267 /**
268 * Returns the set of links stored in the model cache.
269 *
270 * @return set of links
271 */
272 public Set<UiLink> getLinks() {
273 return cache.getAllLinks();
Simon Huntb1ce2602016-07-23 14:04:31 -0700274 }
275
Simon Huntd5b96732016-07-08 13:22:27 -0700276 // =====================================================================
277
278
Simon Hunt642bc452016-05-04 19:34:45 -0700279 /**
280 * Default implementation of service bundle to return references to our
281 * dynamically injected services.
282 */
283 private class DefaultServiceBundle implements ServiceBundle {
284 @Override
285 public ClusterService cluster() {
286 return clusterService;
287 }
288
289 @Override
290 public MastershipService mastership() {
291 return mastershipService;
292 }
293
294 @Override
295 public RegionService region() {
296 return regionService;
297 }
298
299 @Override
300 public DeviceService device() {
301 return deviceService;
302 }
303
304 @Override
305 public LinkService link() {
306 return linkService;
307 }
308
309 @Override
310 public HostService host() {
311 return hostService;
312 }
313
314 @Override
315 public IntentService intent() {
316 return intentService;
317 }
318
319 @Override
320 public FlowRuleService flow() {
321 return flowService;
322 }
323 }
324
Simon Hunt7092cc42016-04-06 18:40:17 -0700325
Simon Huntcda9c032016-04-11 10:32:54 -0700326 private class InternalClusterListener implements ClusterEventListener {
327 @Override
328 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700329 eventHandler.execute(() -> handleEvent(event));
330 }
331
332 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700333 ControllerNode cnode = event.subject();
334
335 switch (event.type()) {
336
337 case INSTANCE_ADDED:
338 case INSTANCE_ACTIVATED:
339 case INSTANCE_READY:
340 case INSTANCE_DEACTIVATED:
341 cache.addOrUpdateClusterMember(cnode);
342 break;
343
344 case INSTANCE_REMOVED:
345 cache.removeClusterMember(cnode);
346 break;
347
348 default:
349 break;
350 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700351 }
Simon Huntcda9c032016-04-11 10:32:54 -0700352 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700353
Simon Huntcda9c032016-04-11 10:32:54 -0700354 private class InternalMastershipListener implements MastershipListener {
355 @Override
356 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700357 DeviceId deviceId = event.subject();
358 RoleInfo roleInfo = event.roleInfo();
359
360 switch (event.type()) {
361 case MASTER_CHANGED:
362 case BACKUPS_CHANGED:
363 cache.updateMasterships(deviceId, roleInfo);
364 break;
365
366 default:
367 break;
368 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700369 }
Simon Huntcda9c032016-04-11 10:32:54 -0700370 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700371
Simon Huntcda9c032016-04-11 10:32:54 -0700372 private class InternalRegionListener implements RegionListener {
373 @Override
374 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700375 Region region = event.subject();
376
377 switch (event.type()) {
378
379 case REGION_ADDED:
380 case REGION_UPDATED:
381 case REGION_MEMBERSHIP_CHANGED:
382 cache.addOrUpdateRegion(region);
383 break;
384
385 case REGION_REMOVED:
386 cache.removeRegion(region);
387 break;
388
389 default:
390 break;
391 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700392 }
Simon Huntcda9c032016-04-11 10:32:54 -0700393 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700394
Simon Huntcda9c032016-04-11 10:32:54 -0700395 private class InternalDeviceListener implements DeviceListener {
396 @Override
397 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700398 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700399
Simon Huntcda9c032016-04-11 10:32:54 -0700400 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700401
Simon Huntcda9c032016-04-11 10:32:54 -0700402 case DEVICE_ADDED:
403 case DEVICE_UPDATED:
404 case DEVICE_AVAILABILITY_CHANGED:
405 case DEVICE_SUSPENDED:
406 cache.addOrUpdateDevice(device);
407 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700408
Simon Huntcda9c032016-04-11 10:32:54 -0700409 case DEVICE_REMOVED:
410 cache.removeDevice(device);
411 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700412
Simon Huntcda9c032016-04-11 10:32:54 -0700413 default:
414 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700415 }
416 }
417 }
418
Simon Huntcda9c032016-04-11 10:32:54 -0700419 private class InternalLinkListener implements LinkListener {
420 @Override
421 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700422 Link link = event.subject();
423
424 switch (event.type()) {
425
426 case LINK_ADDED:
427 case LINK_UPDATED:
428 cache.addOrUpdateLink(link);
429 break;
430
431 case LINK_REMOVED:
432 cache.removeLink(link);
433 break;
434
435 default:
436 break;
437 }
Simon Huntcda9c032016-04-11 10:32:54 -0700438 }
Simon Hunted804d52016-03-30 09:51:40 -0700439 }
440
Simon Huntcda9c032016-04-11 10:32:54 -0700441 private class InternalHostListener implements HostListener {
442 @Override
443 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700444 Host host = event.subject();
445 Host prevHost = event.prevSubject();
446
447 switch (event.type()) {
448
449 case HOST_ADDED:
450 case HOST_UPDATED:
451 cache.addOrUpdateHost(host);
452 break;
453
454 case HOST_MOVED:
455 cache.moveHost(host, prevHost);
456 break;
457
458 case HOST_REMOVED:
459 cache.removeHost(host);
460 break;
461
462 default:
463 break;
464 }
Simon Huntcda9c032016-04-11 10:32:54 -0700465 }
Simon Hunted804d52016-03-30 09:51:40 -0700466 }
Simon Huntcda9c032016-04-11 10:32:54 -0700467
Simon Hunt23fb1352016-04-11 12:15:19 -0700468 // =======================================================================
469 // NOTE: Neither intents nor flows are modeled by the UiTopology.
470 // Rather, they are serviced directly from this class.
471 // Additionally, since we are only retrieving counts (in the current
472 // implementation), we'll fetch them on demand from the service.
473 // Thus, the following internal listeners are stubs only (for now).
474 // =======================================================================
475
Simon Huntcda9c032016-04-11 10:32:54 -0700476 private class InternalIntentListener implements IntentListener {
477 @Override
478 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700479 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700480 }
481 }
482
483 private class InternalFlowRuleListener implements FlowRuleListener {
484 @Override
485 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700486 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700487 }
488 }
489
Simon Hunted804d52016-03-30 09:51:40 -0700490}