Simon Hunt
Committed by Gerrit Code Review

UI topo model - Started fleshing out the UiSharedTopologyModel

 - marked model listeners in TopolgyViewMessageHandler as deprecated.
 - UiWebSocket now creates a (currently inert) UiTopoSession.

Change-Id: Ic385d782a2f56a90565ad744128f8e469678bcc7
...@@ -714,6 +714,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -714,6 +714,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
714 } 714 }
715 715
716 // Cluster event listener. 716 // Cluster event listener.
717 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
718 + @Deprecated
717 private class InternalClusterListener implements ClusterEventListener { 719 private class InternalClusterListener implements ClusterEventListener {
718 @Override 720 @Override
719 public void event(ClusterEvent event) { 721 public void event(ClusterEvent event) {
...@@ -722,6 +724,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -722,6 +724,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
722 } 724 }
723 725
724 // Mastership change listener 726 // Mastership change listener
727 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
728 + @Deprecated
725 private class InternalMastershipListener implements MastershipListener { 729 private class InternalMastershipListener implements MastershipListener {
726 @Override 730 @Override
727 public void event(MastershipEvent event) { 731 public void event(MastershipEvent event) {
...@@ -736,6 +740,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -736,6 +740,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
736 } 740 }
737 741
738 // Device event listener. 742 // Device event listener.
743 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
744 + @Deprecated
739 private class InternalDeviceListener implements DeviceListener { 745 private class InternalDeviceListener implements DeviceListener {
740 @Override 746 @Override
741 public void event(DeviceEvent event) { 747 public void event(DeviceEvent event) {
...@@ -748,6 +754,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -748,6 +754,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
748 } 754 }
749 755
750 // Link event listener. 756 // Link event listener.
757 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
758 + @Deprecated
751 private class InternalLinkListener implements LinkListener { 759 private class InternalLinkListener implements LinkListener {
752 @Override 760 @Override
753 public void event(LinkEvent event) { 761 public void event(LinkEvent event) {
...@@ -758,6 +766,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -758,6 +766,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
758 } 766 }
759 767
760 // Host event listener. 768 // Host event listener.
769 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
770 + @Deprecated
761 private class InternalHostListener implements HostListener { 771 private class InternalHostListener implements HostListener {
762 @Override 772 @Override
763 public void event(HostEvent event) { 773 public void event(HostEvent event) {
...@@ -768,6 +778,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -768,6 +778,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
768 } 778 }
769 779
770 // Intent event listener. 780 // Intent event listener.
781 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
782 + @Deprecated
771 private class InternalIntentListener implements IntentListener { 783 private class InternalIntentListener implements IntentListener {
772 @Override 784 @Override
773 public void event(IntentEvent event) { 785 public void event(IntentEvent event) {
...@@ -777,6 +789,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -777,6 +789,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
777 } 789 }
778 790
779 // Intent event listener. 791 // Intent event listener.
792 + // TODO: Superceded by UiSharedTopologyModel.ModelEventListener
793 + @Deprecated
780 private class InternalFlowListener implements FlowRuleListener { 794 private class InternalFlowListener implements FlowRuleListener {
781 @Override 795 @Override
782 public void event(FlowRuleEvent event) { 796 public void event(FlowRuleEvent event) {
......
...@@ -28,6 +28,7 @@ import org.onosproject.ui.UiExtensionService; ...@@ -28,6 +28,7 @@ import org.onosproject.ui.UiExtensionService;
28 import org.onosproject.ui.UiMessageHandlerFactory; 28 import org.onosproject.ui.UiMessageHandlerFactory;
29 import org.onosproject.ui.UiMessageHandler; 29 import org.onosproject.ui.UiMessageHandler;
30 import org.onosproject.ui.UiTopoOverlayFactory; 30 import org.onosproject.ui.UiTopoOverlayFactory;
31 +import org.onosproject.ui.impl.topo.UiTopoSession;
31 import org.onosproject.ui.topo.TopoConstants; 32 import org.onosproject.ui.topo.TopoConstants;
32 import org.slf4j.Logger; 33 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory; 34 import org.slf4j.LoggerFactory;
...@@ -37,7 +38,7 @@ import java.util.HashMap; ...@@ -37,7 +38,7 @@ import java.util.HashMap;
37 import java.util.Map; 38 import java.util.Map;
38 39
39 /** 40 /**
40 - * Web socket capable of interacting with the GUI. 41 + * Web socket capable of interacting with the Web UI.
41 */ 42 */
42 public class UiWebSocket 43 public class UiWebSocket
43 implements UiConnection, WebSocket.OnTextMessage, WebSocket.OnControl { 44 implements UiConnection, WebSocket.OnTextMessage, WebSocket.OnControl {
...@@ -50,14 +51,14 @@ public class UiWebSocket ...@@ -50,14 +51,14 @@ public class UiWebSocket
50 private static final byte PONG = 0xA; 51 private static final byte PONG = 0xA;
51 private static final byte[] PING_DATA = new byte[]{(byte) 0xde, (byte) 0xad}; 52 private static final byte[] PING_DATA = new byte[]{(byte) 0xde, (byte) 0xad};
52 53
54 + private final ObjectMapper mapper = new ObjectMapper();
53 private final ServiceDirectory directory; 55 private final ServiceDirectory directory;
56 + private final UiTopoSession topoSession;
54 57
55 private Connection connection; 58 private Connection connection;
56 private FrameConnection control; 59 private FrameConnection control;
57 private String userName; 60 private String userName;
58 61
59 - private final ObjectMapper mapper = new ObjectMapper();
60 -
61 private long lastActive = System.currentTimeMillis(); 62 private long lastActive = System.currentTimeMillis();
62 63
63 private Map<String, UiMessageHandler> handlers; 64 private Map<String, UiMessageHandler> handlers;
...@@ -72,6 +73,7 @@ public class UiWebSocket ...@@ -72,6 +73,7 @@ public class UiWebSocket
72 public UiWebSocket(ServiceDirectory directory, String userName) { 73 public UiWebSocket(ServiceDirectory directory, String userName) {
73 this.directory = directory; 74 this.directory = directory;
74 this.userName = userName; 75 this.userName = userName;
76 + this.topoSession = new UiTopoSession(this);
75 } 77 }
76 78
77 @Override 79 @Override
...@@ -115,6 +117,7 @@ public class UiWebSocket ...@@ -115,6 +117,7 @@ public class UiWebSocket
115 this.connection = connection; 117 this.connection = connection;
116 this.control = (FrameConnection) connection; 118 this.control = (FrameConnection) connection;
117 try { 119 try {
120 + topoSession.init();
118 createHandlersAndOverlays(); 121 createHandlersAndOverlays();
119 sendInstanceData(); 122 sendInstanceData();
120 log.info("GUI client connected"); 123 log.info("GUI client connected");
...@@ -129,6 +132,7 @@ public class UiWebSocket ...@@ -129,6 +132,7 @@ public class UiWebSocket
129 132
130 @Override 133 @Override
131 public synchronized void onClose(int closeCode, String message) { 134 public synchronized void onClose(int closeCode, String message) {
135 + topoSession.destroy();
132 destroyHandlersAndOverlays(); 136 destroyHandlersAndOverlays();
133 log.info("GUI client disconnected [close-code={}, message={}]", 137 log.info("GUI client disconnected [close-code={}, message={}]",
134 closeCode, message); 138 closeCode, message);
......
...@@ -36,31 +36,33 @@ import org.slf4j.LoggerFactory; ...@@ -36,31 +36,33 @@ import org.slf4j.LoggerFactory;
36 public class UiTopoSession { 36 public class UiTopoSession {
37 private final Logger log = LoggerFactory.getLogger(getClass()); 37 private final Logger log = LoggerFactory.getLogger(getClass());
38 38
39 - private final String username;
40 private final UiWebSocket webSocket; 39 private final UiWebSocket webSocket;
41 - private final UiSharedTopologyModel sharedModel; 40 + private final String username;
41 +
42 + final UiSharedTopologyModel sharedModel;
42 43
43 private boolean registered = false; 44 private boolean registered = false;
44 45
45 private UiTopoLayoutService service; 46 private UiTopoLayoutService service;
46 - private UiTopoLayout layout; 47 + private UiTopoLayout currentLayout;
47 48
48 /** 49 /**
49 - * Creates a new topology layout. 50 + * Creates a new topology session for the specified web socket connection.
50 - * @param username user name 51 + *
51 * @param webSocket web socket 52 * @param webSocket web socket
52 */ 53 */
53 - public UiTopoSession(String username, UiWebSocket webSocket) { 54 + public UiTopoSession(UiWebSocket webSocket) {
54 - this.username = username;
55 this.webSocket = webSocket; 55 this.webSocket = webSocket;
56 + this.username = webSocket.userName();
56 this.sharedModel = UiSharedTopologyModel.instance(); 57 this.sharedModel = UiSharedTopologyModel.instance();
57 } 58 }
58 59
59 /** 60 /**
60 - * Initializes the layout; registering with the shared model. 61 + * Initializes the session; registering with the shared model.
61 */ 62 */
62 public void init() { 63 public void init() {
63 if (!registered) { 64 if (!registered) {
65 + log.debug("{} : Registering with shared model", this);
64 sharedModel.register(this); 66 sharedModel.register(this);
65 registered = true; 67 registered = true;
66 } else { 68 } else {
...@@ -69,10 +71,11 @@ public class UiTopoSession { ...@@ -69,10 +71,11 @@ public class UiTopoSession {
69 } 71 }
70 72
71 /** 73 /**
72 - * Destroys the layout; unregistering from the shared model. 74 + * Destroys the session; unregistering from the shared model.
73 */ 75 */
74 public void destroy() { 76 public void destroy() {
75 - if (!registered) { 77 + if (registered) {
78 + log.debug("{} : Unregistering from shared model", this);
76 sharedModel.unregister(this); 79 sharedModel.unregister(this);
77 registered = false; 80 registered = false;
78 } else { 81 } else {
......
...@@ -16,10 +16,43 @@ ...@@ -16,10 +16,43 @@
16 16
17 package org.onosproject.ui.impl.topo.model; 17 package org.onosproject.ui.impl.topo.model;
18 18
19 +import org.onlab.osgi.DefaultServiceDirectory;
20 +import org.onlab.osgi.ServiceDirectory;
21 +import org.onosproject.cluster.ClusterEvent;
22 +import org.onosproject.cluster.ClusterEventListener;
23 +import org.onosproject.cluster.ClusterService;
24 +import org.onosproject.incubator.net.PortStatisticsService;
25 +import org.onosproject.incubator.net.tunnel.TunnelService;
26 +import org.onosproject.mastership.MastershipEvent;
27 +import org.onosproject.mastership.MastershipListener;
28 +import org.onosproject.mastership.MastershipService;
29 +import org.onosproject.net.device.DeviceEvent;
30 +import org.onosproject.net.device.DeviceListener;
31 +import org.onosproject.net.device.DeviceService;
32 +import org.onosproject.net.flow.FlowRuleEvent;
33 +import org.onosproject.net.flow.FlowRuleListener;
34 +import org.onosproject.net.flow.FlowRuleService;
35 +import org.onosproject.net.host.HostEvent;
36 +import org.onosproject.net.host.HostListener;
37 +import org.onosproject.net.host.HostService;
38 +import org.onosproject.net.intent.IntentEvent;
39 +import org.onosproject.net.intent.IntentListener;
40 +import org.onosproject.net.intent.IntentService;
41 +import org.onosproject.net.link.LinkEvent;
42 +import org.onosproject.net.link.LinkListener;
43 +import org.onosproject.net.link.LinkService;
44 +import org.onosproject.net.region.RegionEvent;
45 +import org.onosproject.net.region.RegionListener;
46 +import org.onosproject.net.region.RegionService;
47 +import org.onosproject.net.statistic.StatisticService;
48 +import org.onosproject.net.topology.TopologyService;
19 import org.onosproject.ui.impl.topo.UiTopoSession; 49 import org.onosproject.ui.impl.topo.UiTopoSession;
20 import org.slf4j.Logger; 50 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory; 51 import org.slf4j.LoggerFactory;
22 52
53 +import java.util.HashSet;
54 +import java.util.Set;
55 +
23 /** 56 /**
24 * A lazily-initialized Singleton that creates and maintains the UI-model 57 * A lazily-initialized Singleton that creates and maintains the UI-model
25 * of the network topology. 58 * of the network topology.
...@@ -29,15 +62,17 @@ public final class UiSharedTopologyModel { ...@@ -29,15 +62,17 @@ public final class UiSharedTopologyModel {
29 private static final Logger log = 62 private static final Logger log =
30 LoggerFactory.getLogger(UiSharedTopologyModel.class); 63 LoggerFactory.getLogger(UiSharedTopologyModel.class);
31 64
65 + private final ModelEventListener modelEventListener;
32 66
33 - private UiSharedTopologyModel() { 67 + private final Set<UiTopoSession> sessions = new HashSet<>();
34 - // TODO: set up core model listeners and build the state of the model
35 - }
36 68
37 - // TODO: Note to Thomas (or others).. 69 + private UiSharedTopologyModel() {
38 - // Don't we have a common pattern for adding/removing listeners and 70 + modelEventListener = new ModelEventListener().init();
39 - // invoking them when things happen?
40 71
72 + // TODO: build and maintain the state of the model
73 + // (1) query model for current state
74 + // (2) update state as model events arrive
75 + }
41 76
42 /** 77 /**
43 * Registers a UI topology session with the topology model. 78 * Registers a UI topology session with the topology model.
...@@ -46,7 +81,7 @@ public final class UiSharedTopologyModel { ...@@ -46,7 +81,7 @@ public final class UiSharedTopologyModel {
46 */ 81 */
47 public void register(UiTopoSession session) { 82 public void register(UiTopoSession session) {
48 log.info("Registering topology session {}", session); 83 log.info("Registering topology session {}", session);
49 - // TODO: register the session 84 + sessions.add(session);
50 } 85 }
51 86
52 /** 87 /**
...@@ -56,8 +91,122 @@ public final class UiSharedTopologyModel { ...@@ -56,8 +91,122 @@ public final class UiSharedTopologyModel {
56 */ 91 */
57 public void unregister(UiTopoSession session) { 92 public void unregister(UiTopoSession session) {
58 log.info("Unregistering topology session {}", session); 93 log.info("Unregistering topology session {}", session);
59 - // TODO: unregister the session 94 + sessions.remove(session);
95 + }
96 +
97 +
98 + // TODO: notify registered sessions when changes happen to the model
99 +
100 +
101 + // ----------
102 +
103 + // inner class to encapsulate the model listeners
104 + private final class ModelEventListener {
105 +
106 + // TODO: Review - is this good enough? couldn't otherwise see how to inject
107 + private final ServiceDirectory directory = new DefaultServiceDirectory();
108 +
109 + private ClusterService clusterService;
110 + private MastershipService mastershipService;
111 + private RegionService regionService;
112 + private DeviceService deviceService;
113 + private LinkService linkService;
114 + private HostService hostService;
115 + private IntentService intentService;
116 + private FlowRuleService flowService;
117 +
118 + private StatisticService flowStatsService;
119 + private PortStatisticsService portStatsService;
120 + private TopologyService topologyService;
121 + private TunnelService tunnelService;
122 +
123 + private ModelEventListener init() {
124 + clusterService = directory.get(ClusterService.class);
125 + mastershipService = directory.get(MastershipService.class);
126 + regionService = directory.get(RegionService.class);
127 + deviceService = directory.get(DeviceService.class);
128 + linkService = directory.get(LinkService.class);
129 + hostService = directory.get(HostService.class);
130 + intentService = directory.get(IntentService.class);
131 + flowService = directory.get(FlowRuleService.class);
132 +
133 + // passive services (?) to whom we are not listening...
134 + flowStatsService = directory.get(StatisticService.class);
135 + portStatsService = directory.get(PortStatisticsService.class);
136 + topologyService = directory.get(TopologyService.class);
137 + tunnelService = directory.get(TunnelService.class);
138 +
139 + return this;
140 + }
141 +
142 + private class InternalClusterListener implements ClusterEventListener {
143 + @Override
144 + public void event(ClusterEvent event) {
145 + // TODO: handle cluster event
146 + // (1) emit cluster member event
147 + }
148 + }
149 +
150 + private class InternalMastershipListener implements MastershipListener {
151 + @Override
152 + public void event(MastershipEvent event) {
153 + // TODO: handle mastership event
154 + // (1) emit cluster member update for all members
155 + // (2) emit update device event for he whose mastership changed
60 } 156 }
157 + }
158 +
159 + private class InternalRegionListener implements RegionListener {
160 + @Override
161 + public void event(RegionEvent event) {
162 + // TODO: handle region event
163 + // (1) emit region event
164 + }
165 + }
166 +
167 + private class InternalDeviceListener implements DeviceListener {
168 + @Override
169 + public void event(DeviceEvent event) {
170 + // TODO: handle device event
171 + // (1) emit device event
172 + }
173 + }
174 +
175 + private class InternalLinkListener implements LinkListener {
176 + @Override
177 + public void event(LinkEvent event) {
178 + // TODO: handle link event
179 + // (1) consolidate infrastructure links -> UiLink (?)
180 + // (2) emit link event
181 + }
182 + }
183 +
184 + private class InternalHostListener implements HostListener {
185 + @Override
186 + public void event(HostEvent event) {
187 + // TODO: handle host event
188 + // (1) emit host event
189 + }
190 + }
191 +
192 + private class InternalIntentListener implements IntentListener {
193 + @Override
194 + public void event(IntentEvent event) {
195 + // TODO: handle intent event
196 + // (1) update cache of intent counts?
197 + }
198 + }
199 +
200 + private class InternalFlowRuleListener implements FlowRuleListener {
201 + @Override
202 + public void event(FlowRuleEvent event) {
203 + // TODO: handle flowrule event
204 + // (1) update cache of flow counts?
205 + }
206 + }
207 + }
208 +
209 + // ----------
61 210
62 /** 211 /**
63 * Bill Pugh Singleton pattern. INSTANCE won't be instantiated until the 212 * Bill Pugh Singleton pattern. INSTANCE won't be instantiated until the
......