blob: 37ac126391b305729e8acf0016f669a7f215a7fe [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
Madan Jampani492526a2016-06-06 17:24:04 -070019import java.util.concurrent.ExecutorService;
20import java.util.concurrent.Executors;
21
Simon Huntcda9c032016-04-11 10:32:54 -070022import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
24import org.apache.felix.scr.annotations.Deactivate;
25import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.apache.felix.scr.annotations.Service;
Madan Jampani492526a2016-06-06 17:24:04 -070028import org.onlab.util.Tools;
Simon Hunt7092cc42016-04-06 18:40:17 -070029import org.onosproject.cluster.ClusterEvent;
30import org.onosproject.cluster.ClusterEventListener;
31import org.onosproject.cluster.ClusterService;
Simon Hunt23fb1352016-04-11 12:15:19 -070032import org.onosproject.cluster.ControllerNode;
33import org.onosproject.cluster.RoleInfo;
Simon Huntcda9c032016-04-11 10:32:54 -070034import org.onosproject.event.AbstractListenerManager;
Simon Hunt7092cc42016-04-06 18:40:17 -070035import org.onosproject.incubator.net.PortStatisticsService;
36import org.onosproject.incubator.net.tunnel.TunnelService;
37import org.onosproject.mastership.MastershipEvent;
38import org.onosproject.mastership.MastershipListener;
39import org.onosproject.mastership.MastershipService;
Simon Huntcda9c032016-04-11 10:32:54 -070040import org.onosproject.net.Device;
Simon Hunt23fb1352016-04-11 12:15:19 -070041import org.onosproject.net.DeviceId;
42import org.onosproject.net.Host;
43import org.onosproject.net.Link;
Simon Hunt7092cc42016-04-06 18:40:17 -070044import org.onosproject.net.device.DeviceEvent;
45import org.onosproject.net.device.DeviceListener;
46import org.onosproject.net.device.DeviceService;
47import org.onosproject.net.flow.FlowRuleEvent;
48import org.onosproject.net.flow.FlowRuleListener;
49import org.onosproject.net.flow.FlowRuleService;
50import org.onosproject.net.host.HostEvent;
51import org.onosproject.net.host.HostListener;
52import org.onosproject.net.host.HostService;
53import org.onosproject.net.intent.IntentEvent;
54import org.onosproject.net.intent.IntentListener;
55import org.onosproject.net.intent.IntentService;
56import org.onosproject.net.link.LinkEvent;
57import org.onosproject.net.link.LinkListener;
58import org.onosproject.net.link.LinkService;
Simon Hunt23fb1352016-04-11 12:15:19 -070059import org.onosproject.net.region.Region;
Simon Hunt7092cc42016-04-06 18:40:17 -070060import org.onosproject.net.region.RegionEvent;
61import org.onosproject.net.region.RegionListener;
62import org.onosproject.net.region.RegionService;
63import org.onosproject.net.statistic.StatisticService;
64import org.onosproject.net.topology.TopologyService;
Simon Huntf679c4e2016-04-01 17:02:24 -070065import org.onosproject.ui.impl.topo.UiTopoSession;
Simon Hunt642bc452016-05-04 19:34:45 -070066import org.onosproject.ui.model.ServiceBundle;
Simon Hunted804d52016-03-30 09:51:40 -070067import org.slf4j.Logger;
68import org.slf4j.LoggerFactory;
69
70/**
Simon Huntcda9c032016-04-11 10:32:54 -070071 * Service that creates and maintains the UI-model of the network topology.
Simon Hunted804d52016-03-30 09:51:40 -070072 */
Thomas Vachuska92b016b2016-05-20 11:37:57 -070073@Component(immediate = true, enabled = true)
Simon Huntcda9c032016-04-11 10:32:54 -070074@Service(value = UiSharedTopologyModel.class)
75public final class UiSharedTopologyModel
76 extends AbstractListenerManager<UiModelEvent, UiModelListener> {
Simon Hunted804d52016-03-30 09:51:40 -070077
78 private static final Logger log =
79 LoggerFactory.getLogger(UiSharedTopologyModel.class);
80
Simon Huntcda9c032016-04-11 10:32:54 -070081 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
82 private ClusterService clusterService;
83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 private MastershipService mastershipService;
85 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 private RegionService regionService;
87 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 private DeviceService deviceService;
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 private LinkService linkService;
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 private HostService hostService;
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 private IntentService intentService;
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 private FlowRuleService flowService;
Simon Hunt7092cc42016-04-06 18:40:17 -070097
Simon Huntcda9c032016-04-11 10:32:54 -070098 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 private StatisticService flowStatsService;
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 private PortStatisticsService portStatsService;
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 private TopologyService topologyService;
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 private TunnelService tunnelService;
Simon Hunted804d52016-03-30 09:51:40 -0700106
Simon Huntcda9c032016-04-11 10:32:54 -0700107 private final ClusterEventListener clusterListener =
108 new InternalClusterListener();
109 private final MastershipListener mastershipListener =
110 new InternalMastershipListener();
111 private final RegionListener regionListener =
112 new InternalRegionListener();
113 private final DeviceListener deviceListener =
114 new InternalDeviceListener();
115 private final LinkListener linkListener =
116 new InternalLinkListener();
117 private final HostListener hostListener =
118 new InternalHostListener();
119 private final IntentListener intentListener =
120 new InternalIntentListener();
121 private final FlowRuleListener flowRuleListener =
122 new InternalFlowRuleListener();
Simon Hunt7092cc42016-04-06 18:40:17 -0700123
Madan Jampani492526a2016-06-06 17:24:04 -0700124 private ExecutorService eventHandler;
125
Simon Huntcda9c032016-04-11 10:32:54 -0700126
127 private ModelCache cache;
128
129
130 @Activate
131 protected void activate() {
Simon Hunt642bc452016-05-04 19:34:45 -0700132 cache = new ModelCache(new DefaultServiceBundle(), eventDispatcher);
Madan Jampani492526a2016-06-06 17:24:04 -0700133 eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/ui/topo", "event-handler"));
Simon Huntcda9c032016-04-11 10:32:54 -0700134
135 eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
136
137 clusterService.addListener(clusterListener);
138 mastershipService.addListener(mastershipListener);
139 regionService.addListener(regionListener);
140 deviceService.addListener(deviceListener);
141 linkService.addListener(linkListener);
142 hostService.addListener(hostListener);
143 intentService.addListener(intentListener);
144 flowService.addListener(flowRuleListener);
145
146 cache.load();
147
148 log.info("Started");
Simon Hunted804d52016-03-30 09:51:40 -0700149 }
150
Simon Huntcda9c032016-04-11 10:32:54 -0700151 @Deactivate
152 protected void deactivate() {
153 eventDispatcher.removeSink(UiModelEvent.class);
154
155 clusterService.removeListener(clusterListener);
156 mastershipService.removeListener(mastershipListener);
157 regionService.removeListener(regionListener);
158 deviceService.removeListener(deviceListener);
159 linkService.removeListener(linkListener);
160 hostService.removeListener(hostListener);
161 intentService.removeListener(intentListener);
162 flowService.removeListener(flowRuleListener);
163
Madan Jampani492526a2016-06-06 17:24:04 -0700164 eventHandler.shutdown();
165
Simon Huntcda9c032016-04-11 10:32:54 -0700166 cache.clear();
167 cache = null;
168
169 log.info("Stopped");
170 }
171
172
Simon Huntf679c4e2016-04-01 17:02:24 -0700173 /**
174 * Registers a UI topology session with the topology model.
175 *
176 * @param session the session to register
177 */
178 public void register(UiTopoSession session) {
179 log.info("Registering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700180 addListener(session);
Simon Hunted804d52016-03-30 09:51:40 -0700181 }
182
Simon Huntf679c4e2016-04-01 17:02:24 -0700183 /**
184 * Unregisters a UI topology session from the topology model.
185 *
186 * @param session the session to unregister
187 */
188 public void unregister(UiTopoSession session) {
189 log.info("Unregistering topology session {}", session);
Simon Huntcda9c032016-04-11 10:32:54 -0700190 removeListener(session);
Simon Huntf679c4e2016-04-01 17:02:24 -0700191 }
192
Simon Hunt642bc452016-05-04 19:34:45 -0700193 /**
194 * Default implementation of service bundle to return references to our
195 * dynamically injected services.
196 */
197 private class DefaultServiceBundle implements ServiceBundle {
198 @Override
199 public ClusterService cluster() {
200 return clusterService;
201 }
202
203 @Override
204 public MastershipService mastership() {
205 return mastershipService;
206 }
207
208 @Override
209 public RegionService region() {
210 return regionService;
211 }
212
213 @Override
214 public DeviceService device() {
215 return deviceService;
216 }
217
218 @Override
219 public LinkService link() {
220 return linkService;
221 }
222
223 @Override
224 public HostService host() {
225 return hostService;
226 }
227
228 @Override
229 public IntentService intent() {
230 return intentService;
231 }
232
233 @Override
234 public FlowRuleService flow() {
235 return flowService;
236 }
237 }
238
Simon Hunt7092cc42016-04-06 18:40:17 -0700239
Simon Huntcda9c032016-04-11 10:32:54 -0700240 private class InternalClusterListener implements ClusterEventListener {
241 @Override
242 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700243 eventHandler.execute(() -> handleEvent(event));
244 }
245
246 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700247 ControllerNode cnode = event.subject();
248
249 switch (event.type()) {
250
251 case INSTANCE_ADDED:
252 case INSTANCE_ACTIVATED:
253 case INSTANCE_READY:
254 case INSTANCE_DEACTIVATED:
255 cache.addOrUpdateClusterMember(cnode);
256 break;
257
258 case INSTANCE_REMOVED:
259 cache.removeClusterMember(cnode);
260 break;
261
262 default:
263 break;
264 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700265 }
Simon Huntcda9c032016-04-11 10:32:54 -0700266 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700267
Simon Huntcda9c032016-04-11 10:32:54 -0700268 private class InternalMastershipListener implements MastershipListener {
269 @Override
270 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700271 DeviceId deviceId = event.subject();
272 RoleInfo roleInfo = event.roleInfo();
273
274 switch (event.type()) {
275 case MASTER_CHANGED:
276 case BACKUPS_CHANGED:
277 cache.updateMasterships(deviceId, roleInfo);
278 break;
279
280 default:
281 break;
282 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700283 }
Simon Huntcda9c032016-04-11 10:32:54 -0700284 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700285
Simon Huntcda9c032016-04-11 10:32:54 -0700286 private class InternalRegionListener implements RegionListener {
287 @Override
288 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700289 Region region = event.subject();
290
291 switch (event.type()) {
292
293 case REGION_ADDED:
294 case REGION_UPDATED:
295 case REGION_MEMBERSHIP_CHANGED:
296 cache.addOrUpdateRegion(region);
297 break;
298
299 case REGION_REMOVED:
300 cache.removeRegion(region);
301 break;
302
303 default:
304 break;
305 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700306 }
Simon Huntcda9c032016-04-11 10:32:54 -0700307 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700308
Simon Huntcda9c032016-04-11 10:32:54 -0700309 private class InternalDeviceListener implements DeviceListener {
310 @Override
311 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700312 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700313
Simon Huntcda9c032016-04-11 10:32:54 -0700314 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700315
Simon Huntcda9c032016-04-11 10:32:54 -0700316 case DEVICE_ADDED:
317 case DEVICE_UPDATED:
318 case DEVICE_AVAILABILITY_CHANGED:
319 case DEVICE_SUSPENDED:
320 cache.addOrUpdateDevice(device);
321 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700322
Simon Huntcda9c032016-04-11 10:32:54 -0700323 case DEVICE_REMOVED:
324 cache.removeDevice(device);
325 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700326
Simon Huntcda9c032016-04-11 10:32:54 -0700327 default:
328 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700329 }
330 }
331 }
332
Simon Huntcda9c032016-04-11 10:32:54 -0700333 private class InternalLinkListener implements LinkListener {
334 @Override
335 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700336 Link link = event.subject();
337
338 switch (event.type()) {
339
340 case LINK_ADDED:
341 case LINK_UPDATED:
342 cache.addOrUpdateLink(link);
343 break;
344
345 case LINK_REMOVED:
346 cache.removeLink(link);
347 break;
348
349 default:
350 break;
351 }
Simon Huntcda9c032016-04-11 10:32:54 -0700352 }
Simon Hunted804d52016-03-30 09:51:40 -0700353 }
354
Simon Huntcda9c032016-04-11 10:32:54 -0700355 private class InternalHostListener implements HostListener {
356 @Override
357 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700358 Host host = event.subject();
359 Host prevHost = event.prevSubject();
360
361 switch (event.type()) {
362
363 case HOST_ADDED:
364 case HOST_UPDATED:
365 cache.addOrUpdateHost(host);
366 break;
367
368 case HOST_MOVED:
369 cache.moveHost(host, prevHost);
370 break;
371
372 case HOST_REMOVED:
373 cache.removeHost(host);
374 break;
375
376 default:
377 break;
378 }
Simon Huntcda9c032016-04-11 10:32:54 -0700379 }
Simon Hunted804d52016-03-30 09:51:40 -0700380 }
Simon Huntcda9c032016-04-11 10:32:54 -0700381
Simon Hunt23fb1352016-04-11 12:15:19 -0700382 // =======================================================================
383 // NOTE: Neither intents nor flows are modeled by the UiTopology.
384 // Rather, they are serviced directly from this class.
385 // Additionally, since we are only retrieving counts (in the current
386 // implementation), we'll fetch them on demand from the service.
387 // Thus, the following internal listeners are stubs only (for now).
388 // =======================================================================
389
Simon Huntcda9c032016-04-11 10:32:54 -0700390 private class InternalIntentListener implements IntentListener {
391 @Override
392 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700393 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700394 }
395 }
396
397 private class InternalFlowRuleListener implements FlowRuleListener {
398 @Override
399 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700400 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700401 }
402 }
403
Simon Hunted804d52016-03-30 09:51:40 -0700404}