Simon Hunt

Started fleshing out the UI topo model classes.

If reviewing this, please refer to http://tinyurl.com/onos-ui-topo-model

Change-Id: I4738392bec1a89c37dff15eff6fe04d66fcabd95
...@@ -16,8 +16,20 @@ ...@@ -16,8 +16,20 @@
16 16
17 package org.onosproject.ui.model.topo; 17 package org.onosproject.ui.model.topo;
18 18
19 +import java.util.ArrayList;
20 +import java.util.List;
21 +
19 /** 22 /**
20 * Encapsulates the notion of the ONOS cluster. 23 * Encapsulates the notion of the ONOS cluster.
21 */ 24 */
22 -public class UiCluster extends UiElement { 25 +class UiCluster extends UiElement {
26 +
27 + private final List<UiClusterMember> members = new ArrayList<>();
28 +
29 + /**
30 + * Removes all cluster members.
31 + */
32 + void clear() {
33 + members.clear();
34 + }
23 } 35 }
......
...@@ -16,8 +16,17 @@ ...@@ -16,8 +16,17 @@
16 16
17 package org.onosproject.ui.model.topo; 17 package org.onosproject.ui.model.topo;
18 18
19 +import org.onosproject.net.Device;
20 +
19 /** 21 /**
20 * Represents a device. 22 * Represents a device.
21 */ 23 */
22 public class UiDevice extends UiNode { 24 public class UiDevice extends UiNode {
25 +
26 + private Device device;
27 +
28 + @Override
29 + protected void destroy() {
30 + device = null;
31 + }
23 } 32 }
......
...@@ -20,4 +20,12 @@ package org.onosproject.ui.model.topo; ...@@ -20,4 +20,12 @@ package org.onosproject.ui.model.topo;
20 * Abstract base class of all elements in the UI topology model. 20 * Abstract base class of all elements in the UI topology model.
21 */ 21 */
22 public class UiElement { 22 public class UiElement {
23 +
24 + /**
25 + * Removes all external references, and prepares the instance for
26 + * garbage collection. This default implementation does nothing.
27 + */
28 + protected void destroy() {
29 + // does nothing
30 + }
23 } 31 }
......
...@@ -16,8 +16,17 @@ ...@@ -16,8 +16,17 @@
16 16
17 package org.onosproject.ui.model.topo; 17 package org.onosproject.ui.model.topo;
18 18
19 +import org.onosproject.net.Host;
20 +
19 /** 21 /**
20 * Represents an end-station host. 22 * Represents an end-station host.
21 */ 23 */
22 public class UiHost extends UiNode { 24 public class UiHost extends UiNode {
25 +
26 + private Host host;
27 +
28 + @Override
29 + protected void destroy() {
30 + host = null;
31 + }
23 } 32 }
......
...@@ -16,8 +16,42 @@ ...@@ -16,8 +16,42 @@
16 16
17 package org.onosproject.ui.model.topo; 17 package org.onosproject.ui.model.topo;
18 18
19 +import org.onosproject.net.Device;
20 +import org.onosproject.net.EdgeLink;
21 +import org.onosproject.net.Link;
22 +
23 +import java.util.Set;
24 +
19 /** 25 /**
20 * Represents a bi-directional link backed by two uni-directional links. 26 * Represents a bi-directional link backed by two uni-directional links.
21 */ 27 */
22 public class UiLink extends UiElement { 28 public class UiLink extends UiElement {
29 +
30 + // devices at either end of this link
31 + private Device deviceA;
32 + private Device deviceB;
33 +
34 + // two unidirectional links underlying this link...
35 + private Link linkAtoB;
36 + private Link linkBtoA;
37 +
38 + // ==OR== : private (synthetic) host link
39 + private EdgeLink edgeLink;
40 +
41 + // ==OR== : set of underlying UI links that this link aggregates
42 + private Set<UiLink> children;
43 +
44 +
45 + @Override
46 + protected void destroy() {
47 + deviceA = null;
48 + deviceB = null;
49 + linkAtoB = null;
50 + linkBtoA = null;
51 + edgeLink = null;
52 + if (children != null) {
53 + children.clear();
54 + children = null;
55 + }
56 + }
23 } 57 }
......
...@@ -19,5 +19,5 @@ package org.onosproject.ui.model.topo; ...@@ -19,5 +19,5 @@ package org.onosproject.ui.model.topo;
19 /** 19 /**
20 * Represents a node drawn on the topology view (region, device, host). 20 * Represents a node drawn on the topology view (region, device, host).
21 */ 21 */
22 -public abstract class UiNode extends UiElement { 22 +abstract class UiNode extends UiElement {
23 } 23 }
......
...@@ -16,8 +16,34 @@ ...@@ -16,8 +16,34 @@
16 16
17 package org.onosproject.ui.model.topo; 17 package org.onosproject.ui.model.topo;
18 18
19 +import org.onosproject.net.region.Region;
20 +
21 +import java.util.Set;
22 +import java.util.TreeSet;
23 +
19 /** 24 /**
20 * Represents a region. 25 * Represents a region.
21 */ 26 */
22 public class UiRegion extends UiNode { 27 public class UiRegion extends UiNode {
28 +
29 + private final Set<UiDevice> uiDevices = new TreeSet<>();
30 + private final Set<UiHost> uiHosts = new TreeSet<>();
31 + private final Set<UiLink> uiLinks = new TreeSet<>();
32 +
33 + private Region region;
34 +
35 +
36 + @Override
37 + protected void destroy() {
38 + uiDevices.forEach(UiDevice::destroy);
39 + uiHosts.forEach(UiHost::destroy);
40 + uiLinks.forEach(UiLink::destroy);
41 +
42 + uiDevices.clear();
43 + uiHosts.clear();
44 + uiLinks.clear();
45 +
46 + region = null;
47 + }
48 +
23 } 49 }
......
...@@ -16,8 +16,29 @@ ...@@ -16,8 +16,29 @@
16 16
17 package org.onosproject.ui.model.topo; 17 package org.onosproject.ui.model.topo;
18 18
19 +import org.slf4j.Logger;
20 +import org.slf4j.LoggerFactory;
21 +
22 +import java.util.Set;
23 +import java.util.TreeSet;
24 +
19 /** 25 /**
20 * Represents the overall network topology. 26 * Represents the overall network topology.
21 */ 27 */
22 public class UiTopology extends UiElement { 28 public class UiTopology extends UiElement {
29 +
30 + private static final Logger log = LoggerFactory.getLogger(UiTopology.class);
31 +
32 + private final UiCluster uiCluster = new UiCluster();
33 + private final Set<UiRegion> uiRegions = new TreeSet<>();
34 +
35 + /**
36 + * Clears the topology state; that is, drops all regions, devices, hosts,
37 + * links, and cluster members.
38 + */
39 + public void clear() {
40 + log.debug("clearing topology model");
41 + uiRegions.clear();
42 + uiCluster.clear();
43 + }
23 } 44 }
......
...@@ -16,9 +16,19 @@ ...@@ -16,9 +16,19 @@
16 16
17 package org.onosproject.ui.impl.topo.model; 17 package org.onosproject.ui.impl.topo.model;
18 18
19 +import org.onosproject.cluster.ControllerNode;
20 +import org.onosproject.cluster.RoleInfo;
19 import org.onosproject.event.EventDispatcher; 21 import org.onosproject.event.EventDispatcher;
20 import org.onosproject.net.Device; 22 import org.onosproject.net.Device;
23 +import org.onosproject.net.DeviceId;
24 +import org.onosproject.net.Host;
25 +import org.onosproject.net.Link;
26 +import org.onosproject.net.region.Region;
21 import org.onosproject.ui.model.topo.UiDevice; 27 import org.onosproject.ui.model.topo.UiDevice;
28 +import org.onosproject.ui.model.topo.UiTopology;
29 +
30 +import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_ADDED;
31 +import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_REMOVED;
22 32
23 /** 33 /**
24 * UI Topology Model cache. 34 * UI Topology Model cache.
...@@ -26,6 +36,7 @@ import org.onosproject.ui.model.topo.UiDevice; ...@@ -26,6 +36,7 @@ import org.onosproject.ui.model.topo.UiDevice;
26 class ModelCache { 36 class ModelCache {
27 37
28 private final EventDispatcher dispatcher; 38 private final EventDispatcher dispatcher;
39 + private final UiTopology uiTopology = new UiTopology();
29 40
30 ModelCache(EventDispatcher eventDispatcher) { 41 ModelCache(EventDispatcher eventDispatcher) {
31 this.dispatcher = eventDispatcher; 42 this.dispatcher = eventDispatcher;
...@@ -35,7 +46,7 @@ class ModelCache { ...@@ -35,7 +46,7 @@ class ModelCache {
35 * Clear our model. 46 * Clear our model.
36 */ 47 */
37 void clear() { 48 void clear() {
38 - // TODO: clear our internal state 49 + uiTopology.clear();
39 } 50 }
40 51
41 /** 52 /**
...@@ -50,26 +61,72 @@ class ModelCache { ...@@ -50,26 +61,72 @@ class ModelCache {
50 } 61 }
51 62
52 63
53 - // add or update device
54 void addOrUpdateDevice(Device device) { 64 void addOrUpdateDevice(Device device) {
55 - // fetch UiDevice 65 + // TODO: find or create device assoc. with parameter
66 + // FIXME
56 UiDevice uiDevice = new UiDevice(); 67 UiDevice uiDevice = new UiDevice();
57 68
58 - dispatcher.post( 69 + // TODO: post the (correct) event
59 - new UiModelEvent(UiModelEvent.Type.DEVICE_ADDED, uiDevice) 70 + dispatcher.post(new UiModelEvent(DEVICE_ADDED, uiDevice));
60 - );
61 -
62 } 71 }
63 72
64 void removeDevice(Device device) { 73 void removeDevice(Device device) {
74 + // TODO: get UiDevice associated with the given parameter; remove from model
75 + // FIXME
65 UiDevice uiDevice = new UiDevice(); 76 UiDevice uiDevice = new UiDevice();
66 77
67 - dispatcher.post( 78 + // TODO: post the (correct) event
68 - new UiModelEvent(UiModelEvent.Type.DEVICE_REMOVED, uiDevice) 79 + dispatcher.post(new UiModelEvent(DEVICE_REMOVED, uiDevice));
69 - ); 80 +
81 + }
82 +
83 + void addOrUpdateClusterMember(ControllerNode cnode) {
84 + // TODO: find or create cluster member assoc. with parameter
85 + // TODO: post event
86 + }
70 87
88 + void removeClusterMember(ControllerNode cnode) {
89 + // TODO: find cluster member assoc. with parameter; remove from model
90 + // TODO: post event
71 } 91 }
72 92
73 - // TODO remaining model objects
74 93
94 + void updateMasterships(DeviceId deviceId, RoleInfo roleInfo) {
95 + // TODO: store the updated mastership information
96 + // TODO: post event
97 + }
98 +
99 + void addOrUpdateRegion(Region region) {
100 + // TODO: find or create region assoc. with parameter
101 + // TODO: post event
102 + }
103 +
104 + void removeRegion(Region region) {
105 + // TODO: find region assoc. with parameter; remove from model
106 + // TODO: post event
107 + }
108 +
109 + void addOrUpdateLink(Link link) {
110 + // TODO: find ui-link assoc. with parameter; create or update.
111 + // TODO: post event
112 + }
113 +
114 + void removeLink(Link link) {
115 + // TODO: find ui-link assoc. with parameter; update or remove.
116 + // TODO: post event
117 + }
118 +
119 + void addOrUpdateHost(Host host) {
120 + // TODO: find or create host assoc. with parameter
121 + // TODO: post event
122 + }
123 +
124 + void moveHost(Host host, Host prevHost) {
125 + // TODO: process host-move
126 + // TODO: post event
127 + }
128 +
129 + void removeHost(Host host) {
130 + // TODO: find host assoc. with parameter; remove from model
131 + }
75 } 132 }
......
...@@ -25,6 +25,8 @@ import org.apache.felix.scr.annotations.Service; ...@@ -25,6 +25,8 @@ import org.apache.felix.scr.annotations.Service;
25 import org.onosproject.cluster.ClusterEvent; 25 import org.onosproject.cluster.ClusterEvent;
26 import org.onosproject.cluster.ClusterEventListener; 26 import org.onosproject.cluster.ClusterEventListener;
27 import org.onosproject.cluster.ClusterService; 27 import org.onosproject.cluster.ClusterService;
28 +import org.onosproject.cluster.ControllerNode;
29 +import org.onosproject.cluster.RoleInfo;
28 import org.onosproject.event.AbstractListenerManager; 30 import org.onosproject.event.AbstractListenerManager;
29 import org.onosproject.incubator.net.PortStatisticsService; 31 import org.onosproject.incubator.net.PortStatisticsService;
30 import org.onosproject.incubator.net.tunnel.TunnelService; 32 import org.onosproject.incubator.net.tunnel.TunnelService;
...@@ -32,6 +34,9 @@ import org.onosproject.mastership.MastershipEvent; ...@@ -32,6 +34,9 @@ import org.onosproject.mastership.MastershipEvent;
32 import org.onosproject.mastership.MastershipListener; 34 import org.onosproject.mastership.MastershipListener;
33 import org.onosproject.mastership.MastershipService; 35 import org.onosproject.mastership.MastershipService;
34 import org.onosproject.net.Device; 36 import org.onosproject.net.Device;
37 +import org.onosproject.net.DeviceId;
38 +import org.onosproject.net.Host;
39 +import org.onosproject.net.Link;
35 import org.onosproject.net.device.DeviceEvent; 40 import org.onosproject.net.device.DeviceEvent;
36 import org.onosproject.net.device.DeviceListener; 41 import org.onosproject.net.device.DeviceListener;
37 import org.onosproject.net.device.DeviceService; 42 import org.onosproject.net.device.DeviceService;
...@@ -47,6 +52,7 @@ import org.onosproject.net.intent.IntentService; ...@@ -47,6 +52,7 @@ import org.onosproject.net.intent.IntentService;
47 import org.onosproject.net.link.LinkEvent; 52 import org.onosproject.net.link.LinkEvent;
48 import org.onosproject.net.link.LinkListener; 53 import org.onosproject.net.link.LinkListener;
49 import org.onosproject.net.link.LinkService; 54 import org.onosproject.net.link.LinkService;
55 +import org.onosproject.net.region.Region;
50 import org.onosproject.net.region.RegionEvent; 56 import org.onosproject.net.region.RegionEvent;
51 import org.onosproject.net.region.RegionListener; 57 import org.onosproject.net.region.RegionListener;
52 import org.onosproject.net.region.RegionService; 58 import org.onosproject.net.region.RegionService;
...@@ -178,28 +184,71 @@ public final class UiSharedTopologyModel ...@@ -178,28 +184,71 @@ public final class UiSharedTopologyModel
178 private class InternalClusterListener implements ClusterEventListener { 184 private class InternalClusterListener implements ClusterEventListener {
179 @Override 185 @Override
180 public void event(ClusterEvent event) { 186 public void event(ClusterEvent event) {
181 - // TODO: handle cluster event 187 + ControllerNode cnode = event.subject();
188 +
189 + switch (event.type()) {
190 +
191 + case INSTANCE_ADDED:
192 + case INSTANCE_ACTIVATED:
193 + case INSTANCE_READY:
194 + case INSTANCE_DEACTIVATED:
195 + cache.addOrUpdateClusterMember(cnode);
196 + break;
197 +
198 + case INSTANCE_REMOVED:
199 + cache.removeClusterMember(cnode);
200 + break;
201 +
202 + default:
203 + break;
204 + }
182 } 205 }
183 } 206 }
184 207
185 private class InternalMastershipListener implements MastershipListener { 208 private class InternalMastershipListener implements MastershipListener {
186 @Override 209 @Override
187 public void event(MastershipEvent event) { 210 public void event(MastershipEvent event) {
188 - // TODO: handle mastership event 211 + DeviceId deviceId = event.subject();
212 + RoleInfo roleInfo = event.roleInfo();
213 +
214 + switch (event.type()) {
215 + case MASTER_CHANGED:
216 + case BACKUPS_CHANGED:
217 + cache.updateMasterships(deviceId, roleInfo);
218 + break;
219 +
220 + default:
221 + break;
222 + }
189 } 223 }
190 } 224 }
191 225
192 private class InternalRegionListener implements RegionListener { 226 private class InternalRegionListener implements RegionListener {
193 @Override 227 @Override
194 public void event(RegionEvent event) { 228 public void event(RegionEvent event) {
195 - // TODO: handle region event 229 + Region region = event.subject();
230 +
231 + switch (event.type()) {
232 +
233 + case REGION_ADDED:
234 + case REGION_UPDATED:
235 + case REGION_MEMBERSHIP_CHANGED:
236 + cache.addOrUpdateRegion(region);
237 + break;
238 +
239 + case REGION_REMOVED:
240 + cache.removeRegion(region);
241 + break;
242 +
243 + default:
244 + break;
245 + }
196 } 246 }
197 } 247 }
198 248
199 private class InternalDeviceListener implements DeviceListener { 249 private class InternalDeviceListener implements DeviceListener {
200 @Override 250 @Override
201 public void event(DeviceEvent event) { 251 public void event(DeviceEvent event) {
202 -
203 Device device = event.subject(); 252 Device device = event.subject();
204 253
205 switch (event.type()) { 254 switch (event.type()) {
...@@ -224,28 +273,71 @@ public final class UiSharedTopologyModel ...@@ -224,28 +273,71 @@ public final class UiSharedTopologyModel
224 private class InternalLinkListener implements LinkListener { 273 private class InternalLinkListener implements LinkListener {
225 @Override 274 @Override
226 public void event(LinkEvent event) { 275 public void event(LinkEvent event) {
227 - // TODO: handle link event 276 + Link link = event.subject();
277 +
278 + switch (event.type()) {
279 +
280 + case LINK_ADDED:
281 + case LINK_UPDATED:
282 + cache.addOrUpdateLink(link);
283 + break;
284 +
285 + case LINK_REMOVED:
286 + cache.removeLink(link);
287 + break;
288 +
289 + default:
290 + break;
291 + }
228 } 292 }
229 } 293 }
230 294
231 private class InternalHostListener implements HostListener { 295 private class InternalHostListener implements HostListener {
232 @Override 296 @Override
233 public void event(HostEvent event) { 297 public void event(HostEvent event) {
234 - // TODO: handle host event 298 + Host host = event.subject();
299 + Host prevHost = event.prevSubject();
300 +
301 + switch (event.type()) {
302 +
303 + case HOST_ADDED:
304 + case HOST_UPDATED:
305 + cache.addOrUpdateHost(host);
306 + break;
307 +
308 + case HOST_MOVED:
309 + cache.moveHost(host, prevHost);
310 + break;
311 +
312 + case HOST_REMOVED:
313 + cache.removeHost(host);
314 + break;
315 +
316 + default:
317 + break;
318 + }
235 } 319 }
236 } 320 }
237 321
322 + // =======================================================================
323 + // NOTE: Neither intents nor flows are modeled by the UiTopology.
324 + // Rather, they are serviced directly from this class.
325 + // Additionally, since we are only retrieving counts (in the current
326 + // implementation), we'll fetch them on demand from the service.
327 + // Thus, the following internal listeners are stubs only (for now).
328 + // =======================================================================
329 +
238 private class InternalIntentListener implements IntentListener { 330 private class InternalIntentListener implements IntentListener {
239 @Override 331 @Override
240 public void event(IntentEvent event) { 332 public void event(IntentEvent event) {
241 - // TODO: handle intent event 333 + // do nothing (for now)
242 } 334 }
243 } 335 }
244 336
245 private class InternalFlowRuleListener implements FlowRuleListener { 337 private class InternalFlowRuleListener implements FlowRuleListener {
246 @Override 338 @Override
247 public void event(FlowRuleEvent event) { 339 public void event(FlowRuleEvent event) {
248 - // TODO: handle flowrule event 340 + // do nothing (for now)
249 } 341 }
250 } 342 }
251 343
......