blob: 4fbf707fd90694c806ea5b3b5314f44d7e65061a [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 Huntd5b96732016-07-08 13:22:27 -070071import java.util.concurrent.ExecutorService;
72import java.util.concurrent.Executors;
73
Simon Hunted804d52016-03-30 09:51:40 -070074/**
Simon Huntcda9c032016-04-11 10:32:54 -070075 * Service that creates and maintains the UI-model of the network topology.
Simon Hunted804d52016-03-30 09:51:40 -070076 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070077@Component(immediate = true, enabled = true)
Simon Huntcda9c032016-04-11 10:32:54 -070078@Service(value = UiSharedTopologyModel.class)
79public final class UiSharedTopologyModel
80 extends AbstractListenerManager<UiModelEvent, UiModelListener> {
Simon Hunted804d52016-03-30 09:51:40 -070081
82 private static final Logger log =
83 LoggerFactory.getLogger(UiSharedTopologyModel.class);
84
Simon Huntcda9c032016-04-11 10:32:54 -070085 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 private ClusterService clusterService;
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 private MastershipService mastershipService;
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 private RegionService regionService;
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 private DeviceService deviceService;
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 private LinkService linkService;
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 private HostService hostService;
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 private IntentService intentService;
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 private FlowRuleService flowService;
Simon Hunt7092cc42016-04-06 18:40:17 -0700101
Simon Huntcda9c032016-04-11 10:32:54 -0700102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 private StatisticService flowStatsService;
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 private PortStatisticsService portStatsService;
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 private TopologyService topologyService;
108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 private TunnelService tunnelService;
Simon Hunted804d52016-03-30 09:51:40 -0700110
Simon Huntcda9c032016-04-11 10:32:54 -0700111 private final ClusterEventListener clusterListener =
112 new InternalClusterListener();
113 private final MastershipListener mastershipListener =
114 new InternalMastershipListener();
115 private final RegionListener regionListener =
116 new InternalRegionListener();
117 private final DeviceListener deviceListener =
118 new InternalDeviceListener();
119 private final LinkListener linkListener =
120 new InternalLinkListener();
121 private final HostListener hostListener =
122 new InternalHostListener();
123 private final IntentListener intentListener =
124 new InternalIntentListener();
125 private final FlowRuleListener flowRuleListener =
126 new InternalFlowRuleListener();
Simon Hunt7092cc42016-04-06 18:40:17 -0700127
Madan Jampani492526a2016-06-06 17:24:04 -0700128 private ExecutorService eventHandler;
129
Simon Huntcda9c032016-04-11 10:32:54 -0700130
131 private ModelCache cache;
132
133
134 @Activate
135 protected void activate() {
Simon Hunt642bc452016-05-04 19:34:45 -0700136 cache = new ModelCache(new DefaultServiceBundle(), eventDispatcher);
Yuta HIGUCHI1624df12016-07-21 16:54:33 -0700137 eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui/topo", "event-handler", log));
Simon Huntcda9c032016-04-11 10:32:54 -0700138
139 eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
140
141 clusterService.addListener(clusterListener);
142 mastershipService.addListener(mastershipListener);
143 regionService.addListener(regionListener);
144 deviceService.addListener(deviceListener);
145 linkService.addListener(linkListener);
146 hostService.addListener(hostListener);
147 intentService.addListener(intentListener);
148 flowService.addListener(flowRuleListener);
149
150 cache.load();
151
152 log.info("Started");
Simon Hunted804d52016-03-30 09:51:40 -0700153 }
154
Simon Huntcda9c032016-04-11 10:32:54 -0700155 @Deactivate
156 protected void deactivate() {
157 eventDispatcher.removeSink(UiModelEvent.class);
158
159 clusterService.removeListener(clusterListener);
160 mastershipService.removeListener(mastershipListener);
161 regionService.removeListener(regionListener);
162 deviceService.removeListener(deviceListener);
163 linkService.removeListener(linkListener);
164 hostService.removeListener(hostListener);
165 intentService.removeListener(intentListener);
166 flowService.removeListener(flowRuleListener);
167
Madan Jampani492526a2016-06-06 17:24:04 -0700168 eventHandler.shutdown();
169
Simon Huntcda9c032016-04-11 10:32:54 -0700170 cache.clear();
171 cache = null;
172
173 log.info("Stopped");
174 }
175
176
Simon Huntf679c4e2016-04-01 17:02:24 -0700177 /**
178 * Registers a UI topology session with the topology model.
179 *
180 * @param session the session to register
181 */
182 public void register(UiTopoSession session) {
183 log.info("Registering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700184 addListener(session);
Simon Hunted804d52016-03-30 09:51:40 -0700185 }
186
Simon Huntf679c4e2016-04-01 17:02:24 -0700187 /**
188 * Unregisters a UI topology session from the topology model.
189 *
190 * @param session the session to unregister
191 */
192 public void unregister(UiTopoSession session) {
193 log.info("Unregistering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700194 removeListener(session);
Simon Huntf679c4e2016-04-01 17:02:24 -0700195 }
196
Simon Huntd5b96732016-07-08 13:22:27 -0700197
198 // =======================================================================
199 // methods that the topo session will use to extract information from us
200
201 /**
202 * Returns the list of cluster members stored in our model cache.
203 *
204 * @return list of cluster members
205 */
206 public List<UiClusterMember> getClusterMembers() {
207 return cache.getAllClusterMembers();
208 }
209
Simon Huntd5b96732016-07-08 13:22:27 -0700210 /**
Simon Hunt977aa052016-07-20 17:08:29 -0700211 * Returns the region for the given identifier.
Simon Huntd5b96732016-07-08 13:22:27 -0700212 *
Simon Hunt977aa052016-07-20 17:08:29 -0700213 * @param id region identifier
214 * @return the region
Simon Huntd5b96732016-07-08 13:22:27 -0700215 */
Simon Hunt977aa052016-07-20 17:08:29 -0700216 public UiRegion getRegion(RegionId id) {
217 return cache.accessRegion(id);
Simon Huntd5b96732016-07-08 13:22:27 -0700218 }
219
Simon Huntb1ce2602016-07-23 14:04:31 -0700220 /**
221 * Returns the null region.
222 *
223 * @return the null region
224 */
225 public UiRegion getNullRegion() {
226 return cache.nullRegion();
227 }
228
229 /**
230 * Refreshes the cache's internal state.
231 */
232 public void refresh() {
233 cache.refresh();
234 }
235
Simon Huntd5b96732016-07-08 13:22:27 -0700236 // =====================================================================
237
238
Simon Hunt642bc452016-05-04 19:34:45 -0700239 /**
240 * Default implementation of service bundle to return references to our
241 * dynamically injected services.
242 */
243 private class DefaultServiceBundle implements ServiceBundle {
244 @Override
245 public ClusterService cluster() {
246 return clusterService;
247 }
248
249 @Override
250 public MastershipService mastership() {
251 return mastershipService;
252 }
253
254 @Override
255 public RegionService region() {
256 return regionService;
257 }
258
259 @Override
260 public DeviceService device() {
261 return deviceService;
262 }
263
264 @Override
265 public LinkService link() {
266 return linkService;
267 }
268
269 @Override
270 public HostService host() {
271 return hostService;
272 }
273
274 @Override
275 public IntentService intent() {
276 return intentService;
277 }
278
279 @Override
280 public FlowRuleService flow() {
281 return flowService;
282 }
283 }
284
Simon Hunt7092cc42016-04-06 18:40:17 -0700285
Simon Huntcda9c032016-04-11 10:32:54 -0700286 private class InternalClusterListener implements ClusterEventListener {
287 @Override
288 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700289 eventHandler.execute(() -> handleEvent(event));
290 }
291
292 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700293 ControllerNode cnode = event.subject();
294
295 switch (event.type()) {
296
297 case INSTANCE_ADDED:
298 case INSTANCE_ACTIVATED:
299 case INSTANCE_READY:
300 case INSTANCE_DEACTIVATED:
301 cache.addOrUpdateClusterMember(cnode);
302 break;
303
304 case INSTANCE_REMOVED:
305 cache.removeClusterMember(cnode);
306 break;
307
308 default:
309 break;
310 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700311 }
Simon Huntcda9c032016-04-11 10:32:54 -0700312 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700313
Simon Huntcda9c032016-04-11 10:32:54 -0700314 private class InternalMastershipListener implements MastershipListener {
315 @Override
316 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700317 DeviceId deviceId = event.subject();
318 RoleInfo roleInfo = event.roleInfo();
319
320 switch (event.type()) {
321 case MASTER_CHANGED:
322 case BACKUPS_CHANGED:
323 cache.updateMasterships(deviceId, roleInfo);
324 break;
325
326 default:
327 break;
328 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700329 }
Simon Huntcda9c032016-04-11 10:32:54 -0700330 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700331
Simon Huntcda9c032016-04-11 10:32:54 -0700332 private class InternalRegionListener implements RegionListener {
333 @Override
334 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700335 Region region = event.subject();
336
337 switch (event.type()) {
338
339 case REGION_ADDED:
340 case REGION_UPDATED:
341 case REGION_MEMBERSHIP_CHANGED:
342 cache.addOrUpdateRegion(region);
343 break;
344
345 case REGION_REMOVED:
346 cache.removeRegion(region);
347 break;
348
349 default:
350 break;
351 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700352 }
Simon Huntcda9c032016-04-11 10:32:54 -0700353 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700354
Simon Huntcda9c032016-04-11 10:32:54 -0700355 private class InternalDeviceListener implements DeviceListener {
356 @Override
357 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700358 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700359
Simon Huntcda9c032016-04-11 10:32:54 -0700360 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700361
Simon Huntcda9c032016-04-11 10:32:54 -0700362 case DEVICE_ADDED:
363 case DEVICE_UPDATED:
364 case DEVICE_AVAILABILITY_CHANGED:
365 case DEVICE_SUSPENDED:
366 cache.addOrUpdateDevice(device);
367 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700368
Simon Huntcda9c032016-04-11 10:32:54 -0700369 case DEVICE_REMOVED:
370 cache.removeDevice(device);
371 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700372
Simon Huntcda9c032016-04-11 10:32:54 -0700373 default:
374 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700375 }
376 }
377 }
378
Simon Huntcda9c032016-04-11 10:32:54 -0700379 private class InternalLinkListener implements LinkListener {
380 @Override
381 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700382 Link link = event.subject();
383
384 switch (event.type()) {
385
386 case LINK_ADDED:
387 case LINK_UPDATED:
388 cache.addOrUpdateLink(link);
389 break;
390
391 case LINK_REMOVED:
392 cache.removeLink(link);
393 break;
394
395 default:
396 break;
397 }
Simon Huntcda9c032016-04-11 10:32:54 -0700398 }
Simon Hunted804d52016-03-30 09:51:40 -0700399 }
400
Simon Huntcda9c032016-04-11 10:32:54 -0700401 private class InternalHostListener implements HostListener {
402 @Override
403 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700404 Host host = event.subject();
405 Host prevHost = event.prevSubject();
406
407 switch (event.type()) {
408
409 case HOST_ADDED:
410 case HOST_UPDATED:
411 cache.addOrUpdateHost(host);
412 break;
413
414 case HOST_MOVED:
415 cache.moveHost(host, prevHost);
416 break;
417
418 case HOST_REMOVED:
419 cache.removeHost(host);
420 break;
421
422 default:
423 break;
424 }
Simon Huntcda9c032016-04-11 10:32:54 -0700425 }
Simon Hunted804d52016-03-30 09:51:40 -0700426 }
Simon Huntcda9c032016-04-11 10:32:54 -0700427
Simon Hunt23fb1352016-04-11 12:15:19 -0700428 // =======================================================================
429 // NOTE: Neither intents nor flows are modeled by the UiTopology.
430 // Rather, they are serviced directly from this class.
431 // Additionally, since we are only retrieving counts (in the current
432 // implementation), we'll fetch them on demand from the service.
433 // Thus, the following internal listeners are stubs only (for now).
434 // =======================================================================
435
Simon Huntcda9c032016-04-11 10:32:54 -0700436 private class InternalIntentListener implements IntentListener {
437 @Override
438 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700439 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700440 }
441 }
442
443 private class InternalFlowRuleListener implements FlowRuleListener {
444 @Override
445 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700446 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700447 }
448 }
449
Simon Hunted804d52016-03-30 09:51:40 -0700450}