blob: 50ebb06050533733b26273a249d736cb8a3bbacc [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
220 // =====================================================================
221
222
Simon Hunt642bc452016-05-04 19:34:45 -0700223 /**
224 * Default implementation of service bundle to return references to our
225 * dynamically injected services.
226 */
227 private class DefaultServiceBundle implements ServiceBundle {
228 @Override
229 public ClusterService cluster() {
230 return clusterService;
231 }
232
233 @Override
234 public MastershipService mastership() {
235 return mastershipService;
236 }
237
238 @Override
239 public RegionService region() {
240 return regionService;
241 }
242
243 @Override
244 public DeviceService device() {
245 return deviceService;
246 }
247
248 @Override
249 public LinkService link() {
250 return linkService;
251 }
252
253 @Override
254 public HostService host() {
255 return hostService;
256 }
257
258 @Override
259 public IntentService intent() {
260 return intentService;
261 }
262
263 @Override
264 public FlowRuleService flow() {
265 return flowService;
266 }
267 }
268
Simon Hunt7092cc42016-04-06 18:40:17 -0700269
Simon Huntcda9c032016-04-11 10:32:54 -0700270 private class InternalClusterListener implements ClusterEventListener {
271 @Override
272 public void event(ClusterEvent event) {
Madan Jampani492526a2016-06-06 17:24:04 -0700273 eventHandler.execute(() -> handleEvent(event));
274 }
275
276 private void handleEvent(ClusterEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700277 ControllerNode cnode = event.subject();
278
279 switch (event.type()) {
280
281 case INSTANCE_ADDED:
282 case INSTANCE_ACTIVATED:
283 case INSTANCE_READY:
284 case INSTANCE_DEACTIVATED:
285 cache.addOrUpdateClusterMember(cnode);
286 break;
287
288 case INSTANCE_REMOVED:
289 cache.removeClusterMember(cnode);
290 break;
291
292 default:
293 break;
294 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700295 }
Simon Huntcda9c032016-04-11 10:32:54 -0700296 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700297
Simon Huntcda9c032016-04-11 10:32:54 -0700298 private class InternalMastershipListener implements MastershipListener {
299 @Override
300 public void event(MastershipEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700301 DeviceId deviceId = event.subject();
302 RoleInfo roleInfo = event.roleInfo();
303
304 switch (event.type()) {
305 case MASTER_CHANGED:
306 case BACKUPS_CHANGED:
307 cache.updateMasterships(deviceId, roleInfo);
308 break;
309
310 default:
311 break;
312 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700313 }
Simon Huntcda9c032016-04-11 10:32:54 -0700314 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700315
Simon Huntcda9c032016-04-11 10:32:54 -0700316 private class InternalRegionListener implements RegionListener {
317 @Override
318 public void event(RegionEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700319 Region region = event.subject();
320
321 switch (event.type()) {
322
323 case REGION_ADDED:
324 case REGION_UPDATED:
325 case REGION_MEMBERSHIP_CHANGED:
326 cache.addOrUpdateRegion(region);
327 break;
328
329 case REGION_REMOVED:
330 cache.removeRegion(region);
331 break;
332
333 default:
334 break;
335 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700336 }
Simon Huntcda9c032016-04-11 10:32:54 -0700337 }
Simon Hunt7092cc42016-04-06 18:40:17 -0700338
Simon Huntcda9c032016-04-11 10:32:54 -0700339 private class InternalDeviceListener implements DeviceListener {
340 @Override
341 public void event(DeviceEvent event) {
Simon Huntcda9c032016-04-11 10:32:54 -0700342 Device device = event.subject();
Simon Hunt7092cc42016-04-06 18:40:17 -0700343
Simon Huntcda9c032016-04-11 10:32:54 -0700344 switch (event.type()) {
Simon Hunt7092cc42016-04-06 18:40:17 -0700345
Simon Huntcda9c032016-04-11 10:32:54 -0700346 case DEVICE_ADDED:
347 case DEVICE_UPDATED:
348 case DEVICE_AVAILABILITY_CHANGED:
349 case DEVICE_SUSPENDED:
350 cache.addOrUpdateDevice(device);
351 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700352
Simon Huntcda9c032016-04-11 10:32:54 -0700353 case DEVICE_REMOVED:
354 cache.removeDevice(device);
355 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700356
Simon Huntcda9c032016-04-11 10:32:54 -0700357 default:
358 break;
Simon Hunt7092cc42016-04-06 18:40:17 -0700359 }
360 }
361 }
362
Simon Huntcda9c032016-04-11 10:32:54 -0700363 private class InternalLinkListener implements LinkListener {
364 @Override
365 public void event(LinkEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700366 Link link = event.subject();
367
368 switch (event.type()) {
369
370 case LINK_ADDED:
371 case LINK_UPDATED:
372 cache.addOrUpdateLink(link);
373 break;
374
375 case LINK_REMOVED:
376 cache.removeLink(link);
377 break;
378
379 default:
380 break;
381 }
Simon Huntcda9c032016-04-11 10:32:54 -0700382 }
Simon Hunted804d52016-03-30 09:51:40 -0700383 }
384
Simon Huntcda9c032016-04-11 10:32:54 -0700385 private class InternalHostListener implements HostListener {
386 @Override
387 public void event(HostEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700388 Host host = event.subject();
389 Host prevHost = event.prevSubject();
390
391 switch (event.type()) {
392
393 case HOST_ADDED:
394 case HOST_UPDATED:
395 cache.addOrUpdateHost(host);
396 break;
397
398 case HOST_MOVED:
399 cache.moveHost(host, prevHost);
400 break;
401
402 case HOST_REMOVED:
403 cache.removeHost(host);
404 break;
405
406 default:
407 break;
408 }
Simon Huntcda9c032016-04-11 10:32:54 -0700409 }
Simon Hunted804d52016-03-30 09:51:40 -0700410 }
Simon Huntcda9c032016-04-11 10:32:54 -0700411
Simon Hunt23fb1352016-04-11 12:15:19 -0700412 // =======================================================================
413 // NOTE: Neither intents nor flows are modeled by the UiTopology.
414 // Rather, they are serviced directly from this class.
415 // Additionally, since we are only retrieving counts (in the current
416 // implementation), we'll fetch them on demand from the service.
417 // Thus, the following internal listeners are stubs only (for now).
418 // =======================================================================
419
Simon Huntcda9c032016-04-11 10:32:54 -0700420 private class InternalIntentListener implements IntentListener {
421 @Override
422 public void event(IntentEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700423 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700424 }
425 }
426
427 private class InternalFlowRuleListener implements FlowRuleListener {
428 @Override
429 public void event(FlowRuleEvent event) {
Simon Hunt23fb1352016-04-11 12:15:19 -0700430 // do nothing (for now)
Simon Huntcda9c032016-04-11 10:32:54 -0700431 }
432 }
433
Simon Hunted804d52016-03-30 09:51:40 -0700434}