ONOS-4971: Synthetic Link Data -- WIP, merge anyway
- created temp Topology2 View (topoX) to "process" and display topology data. - made root layout parent of itself (just like /.. = /) to simplify layout hierarchy operations. - added nodeType property to JSON rep of regions/devices/hosts. - augmented peers to include devices. - added skeleton topo2NavRegion event. Change-Id: I8219125d7dfe33d211350ae27111a3d9de6eb4ca
Showing
19 changed files
with
869 additions
and
21 deletions
... | @@ -63,7 +63,7 @@ public interface UiTopoLayoutService { | ... | @@ -63,7 +63,7 @@ public interface UiTopoLayoutService { |
63 | * @param layoutId layout identifier | 63 | * @param layoutId layout identifier |
64 | * @return set of peer layouts; empty set if layout has no peers | 64 | * @return set of peer layouts; empty set if layout has no peers |
65 | */ | 65 | */ |
66 | - Set<UiTopoLayout> getPeers(UiTopoLayoutId layoutId); | 66 | + Set<UiTopoLayout> getPeerLayouts(UiTopoLayoutId layoutId); |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Returns the set of the child layouts of the specified layout. | 69 | * Returns the set of the child layouts of the specified layout. | ... | ... |
... | @@ -39,7 +39,8 @@ public class UiTopoLayout { | ... | @@ -39,7 +39,8 @@ public class UiTopoLayout { |
39 | public UiTopoLayout(UiTopoLayoutId id, Region region, UiTopoLayoutId parent) { | 39 | public UiTopoLayout(UiTopoLayoutId id, Region region, UiTopoLayoutId parent) { |
40 | this.id = id; | 40 | this.id = id; |
41 | this.region = region; | 41 | this.region = region; |
42 | - this.parent = parent; | 42 | + // NOTE: root layout is its own parent... |
43 | + this.parent = parent != null ? parent : this.id; | ||
43 | } | 44 | } |
44 | 45 | ||
45 | @Override | 46 | @Override |
... | @@ -85,5 +86,13 @@ public class UiTopoLayout { | ... | @@ -85,5 +86,13 @@ public class UiTopoLayout { |
85 | return parent; | 86 | return parent; |
86 | } | 87 | } |
87 | 88 | ||
88 | - // TODO: additional properties pertinent to the layout | 89 | + /** |
90 | + * Returns true if this layout instance is at the top of the | ||
91 | + * hierarchy tree. | ||
92 | + * | ||
93 | + * @return true if this is the root layout | ||
94 | + */ | ||
95 | + public boolean isRoot() { | ||
96 | + return id.equals(parent); | ||
97 | + } | ||
89 | } | 98 | } | ... | ... |
... | @@ -134,6 +134,7 @@ public class UiExtensionManager | ... | @@ -134,6 +134,7 @@ public class UiExtensionManager |
134 | 134 | ||
135 | // FIXME: leave commented out for now, while still under development | 135 | // FIXME: leave commented out for now, while still under development |
136 | // new UiView(NETWORK, "topo2", "New-Topo"), | 136 | // new UiView(NETWORK, "topo2", "New-Topo"), |
137 | +// new UiView(NETWORK, "topoX", "Topo-X"), | ||
137 | 138 | ||
138 | new UiView(NETWORK, "device", "Devices", "nav_devs"), | 139 | new UiView(NETWORK, "device", "Devices", "nav_devs"), |
139 | new UiViewHidden("flow"), | 140 | new UiViewHidden("flow"), | ... | ... |
... | @@ -40,6 +40,8 @@ import org.onosproject.ui.model.topo.UiLink; | ... | @@ -40,6 +40,8 @@ import org.onosproject.ui.model.topo.UiLink; |
40 | import org.onosproject.ui.model.topo.UiNode; | 40 | import org.onosproject.ui.model.topo.UiNode; |
41 | import org.onosproject.ui.model.topo.UiRegion; | 41 | import org.onosproject.ui.model.topo.UiRegion; |
42 | import org.onosproject.ui.model.topo.UiTopoLayout; | 42 | import org.onosproject.ui.model.topo.UiTopoLayout; |
43 | +import org.slf4j.Logger; | ||
44 | +import org.slf4j.LoggerFactory; | ||
43 | 45 | ||
44 | import java.util.ArrayList; | 46 | import java.util.ArrayList; |
45 | import java.util.HashMap; | 47 | import java.util.HashMap; |
... | @@ -62,6 +64,12 @@ class Topo2Jsonifier { | ... | @@ -62,6 +64,12 @@ class Topo2Jsonifier { |
62 | private static final String E_UNKNOWN_UI_NODE = | 64 | private static final String E_UNKNOWN_UI_NODE = |
63 | "Unknown subclass of UiNode: "; | 65 | "Unknown subclass of UiNode: "; |
64 | 66 | ||
67 | + private static final String REGION = "region"; | ||
68 | + private static final String DEVICE = "device"; | ||
69 | + private static final String HOST = "host"; | ||
70 | + | ||
71 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
72 | + | ||
65 | private final ObjectMapper mapper = new ObjectMapper(); | 73 | private final ObjectMapper mapper = new ObjectMapper(); |
66 | 74 | ||
67 | private ServiceDirectory directory; | 75 | private ServiceDirectory directory; |
... | @@ -245,6 +253,7 @@ class Topo2Jsonifier { | ... | @@ -245,6 +253,7 @@ class Topo2Jsonifier { |
245 | private ObjectNode json(UiDevice device) { | 253 | private ObjectNode json(UiDevice device) { |
246 | ObjectNode node = objectNode() | 254 | ObjectNode node = objectNode() |
247 | .put("id", device.idAsString()) | 255 | .put("id", device.idAsString()) |
256 | + .put("nodeType", DEVICE) | ||
248 | .put("type", device.type()) | 257 | .put("type", device.type()) |
249 | .put("online", device.isOnline()) | 258 | .put("online", device.isOnline()) |
250 | .put("master", nullIsEmpty(device.master())) | 259 | .put("master", nullIsEmpty(device.master())) |
... | @@ -266,6 +275,7 @@ class Topo2Jsonifier { | ... | @@ -266,6 +275,7 @@ class Topo2Jsonifier { |
266 | private ObjectNode json(UiHost host) { | 275 | private ObjectNode json(UiHost host) { |
267 | return objectNode() | 276 | return objectNode() |
268 | .put("id", host.idAsString()) | 277 | .put("id", host.idAsString()) |
278 | + .put("nodeType", HOST) | ||
269 | .put("layer", host.layer()); | 279 | .put("layer", host.layer()); |
270 | // TODO: complete host details | 280 | // TODO: complete host details |
271 | } | 281 | } |
... | @@ -281,10 +291,31 @@ class Topo2Jsonifier { | ... | @@ -281,10 +291,31 @@ class Topo2Jsonifier { |
281 | private ObjectNode jsonClosedRegion(UiRegion region) { | 291 | private ObjectNode jsonClosedRegion(UiRegion region) { |
282 | return objectNode() | 292 | return objectNode() |
283 | .put("id", region.idAsString()) | 293 | .put("id", region.idAsString()) |
294 | + .put("nodeType", REGION) | ||
284 | .put("nDevs", region.deviceCount()); | 295 | .put("nDevs", region.deviceCount()); |
285 | // TODO: complete closed-region details | 296 | // TODO: complete closed-region details |
286 | } | 297 | } |
287 | 298 | ||
299 | + /** | ||
300 | + * Returns a JSON array representation of a set of regions/devices. Note | ||
301 | + * that the information is sufficient for showing regions as nodes. | ||
302 | + * | ||
303 | + * @param nodes the nodes | ||
304 | + * @return a JSON representation of the nodes | ||
305 | + */ | ||
306 | + public ArrayNode closedNodes(Set<UiNode> nodes) { | ||
307 | + ArrayNode array = arrayNode(); | ||
308 | + for (UiNode node: nodes) { | ||
309 | + if (node instanceof UiRegion) { | ||
310 | + array.add(jsonClosedRegion((UiRegion) node)); | ||
311 | + } else if (node instanceof UiDevice) { | ||
312 | + array.add(json((UiDevice) node)); | ||
313 | + } else { | ||
314 | + log.warn("Unexpected node instance: {}", node.getClass()); | ||
315 | + } | ||
316 | + } | ||
317 | + return array; | ||
318 | + } | ||
288 | 319 | ||
289 | /** | 320 | /** |
290 | * Returns a JSON array representation of a list of regions. Note that the | 321 | * Returns a JSON array representation of a list of regions. Note that the | ... | ... |
... | @@ -24,6 +24,7 @@ import org.onosproject.ui.UiConnection; | ... | @@ -24,6 +24,7 @@ import org.onosproject.ui.UiConnection; |
24 | import org.onosproject.ui.UiMessageHandler; | 24 | import org.onosproject.ui.UiMessageHandler; |
25 | import org.onosproject.ui.impl.UiWebSocket; | 25 | import org.onosproject.ui.impl.UiWebSocket; |
26 | import org.onosproject.ui.model.topo.UiClusterMember; | 26 | import org.onosproject.ui.model.topo.UiClusterMember; |
27 | +import org.onosproject.ui.model.topo.UiNode; | ||
27 | import org.onosproject.ui.model.topo.UiRegion; | 28 | import org.onosproject.ui.model.topo.UiRegion; |
28 | import org.onosproject.ui.model.topo.UiTopoLayout; | 29 | import org.onosproject.ui.model.topo.UiTopoLayout; |
29 | import org.slf4j.Logger; | 30 | import org.slf4j.Logger; |
... | @@ -55,8 +56,9 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { | ... | @@ -55,8 +56,9 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { |
55 | private final Logger log = LoggerFactory.getLogger(getClass()); | 56 | private final Logger log = LoggerFactory.getLogger(getClass()); |
56 | 57 | ||
57 | // === Inbound event identifiers | 58 | // === Inbound event identifiers |
58 | - private static final String TOPO2_START = "topo2Start"; | 59 | + private static final String START = "topo2Start"; |
59 | - private static final String TOPO2_STOP = "topo2Stop"; | 60 | + private static final String NAV_REGION = "topo2navRegion"; |
61 | + private static final String STOP = "topo2Stop"; | ||
60 | 62 | ||
61 | // === Outbound event identifiers | 63 | // === Outbound event identifiers |
62 | private static final String ALL_INSTANCES = "topo2AllInstances"; | 64 | private static final String ALL_INSTANCES = "topo2AllInstances"; |
... | @@ -83,6 +85,7 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { | ... | @@ -83,6 +85,7 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { |
83 | protected Collection<RequestHandler> createRequestHandlers() { | 85 | protected Collection<RequestHandler> createRequestHandlers() { |
84 | return ImmutableSet.of( | 86 | return ImmutableSet.of( |
85 | new Topo2Start(), | 87 | new Topo2Start(), |
88 | + new Topo2NavRegion(), | ||
86 | new Topo2Stop() | 89 | new Topo2Stop() |
87 | ); | 90 | ); |
88 | } | 91 | } |
... | @@ -92,7 +95,7 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { | ... | @@ -92,7 +95,7 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { |
92 | 95 | ||
93 | private final class Topo2Start extends RequestHandler { | 96 | private final class Topo2Start extends RequestHandler { |
94 | private Topo2Start() { | 97 | private Topo2Start() { |
95 | - super(TOPO2_START); | 98 | + super(START); |
96 | } | 99 | } |
97 | 100 | ||
98 | @Override | 101 | @Override |
... | @@ -124,10 +127,10 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { | ... | @@ -124,10 +127,10 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { |
124 | Set<UiRegion> kids = topoSession.getSubRegions(currentLayout); | 127 | Set<UiRegion> kids = topoSession.getSubRegions(currentLayout); |
125 | sendMessage(CURRENT_REGION, t2json.region(region, kids)); | 128 | sendMessage(CURRENT_REGION, t2json.region(region, kids)); |
126 | 129 | ||
127 | - // these are the regions that are siblings to this one | 130 | + // these are the regions/devices that are siblings to this region |
128 | - Set<UiRegion> peers = topoSession.getPeerRegions(currentLayout); | 131 | + Set<UiNode> peers = topoSession.getPeerNodes(currentLayout); |
129 | ObjectNode peersPayload = objectNode(); | 132 | ObjectNode peersPayload = objectNode(); |
130 | - peersPayload.set("peers", t2json.closedRegions(peers)); | 133 | + peersPayload.set("peers", t2json.closedNodes(peers)); |
131 | sendMessage(PEER_REGIONS, peersPayload); | 134 | sendMessage(PEER_REGIONS, peersPayload); |
132 | 135 | ||
133 | // finally, tell the UI that we are done : TODO review / delete?? | 136 | // finally, tell the UI that we are done : TODO review / delete?? |
... | @@ -146,9 +149,22 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { | ... | @@ -146,9 +149,22 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { |
146 | 149 | ||
147 | } | 150 | } |
148 | 151 | ||
152 | + private final class Topo2NavRegion extends RequestHandler { | ||
153 | + private Topo2NavRegion() { | ||
154 | + super(NAV_REGION); | ||
155 | + } | ||
156 | + | ||
157 | + @Override | ||
158 | + public void process(long sid, ObjectNode payload) { | ||
159 | + String dir = string(payload, "dir"); | ||
160 | + String rid = string(payload, "rid"); | ||
161 | + log.debug("NavRegion: dir={}, rid={}", dir, rid); | ||
162 | + } | ||
163 | + } | ||
164 | + | ||
149 | private final class Topo2Stop extends RequestHandler { | 165 | private final class Topo2Stop extends RequestHandler { |
150 | private Topo2Stop() { | 166 | private Topo2Stop() { |
151 | - super(TOPO2_STOP); | 167 | + super(STOP); |
152 | } | 168 | } |
153 | 169 | ||
154 | @Override | 170 | @Override | ... | ... |
... | @@ -111,15 +111,17 @@ public class UiTopoLayoutManager implements UiTopoLayoutService { | ... | @@ -111,15 +111,17 @@ public class UiTopoLayoutManager implements UiTopoLayoutService { |
111 | } | 111 | } |
112 | 112 | ||
113 | @Override | 113 | @Override |
114 | - public Set<UiTopoLayout> getPeers(UiTopoLayoutId layoutId) { | 114 | + public Set<UiTopoLayout> getPeerLayouts(UiTopoLayoutId layoutId) { |
115 | checkNotNull(layoutId, ID_NULL); | 115 | checkNotNull(layoutId, ID_NULL); |
116 | + | ||
116 | UiTopoLayout layout = layoutMap.get(layoutId); | 117 | UiTopoLayout layout = layoutMap.get(layoutId); |
117 | - if (layout == null) { | 118 | + if (layout == null || layout.isRoot()) { |
118 | return Collections.emptySet(); | 119 | return Collections.emptySet(); |
119 | } | 120 | } |
120 | 121 | ||
121 | UiTopoLayoutId parentId = layout.parent(); | 122 | UiTopoLayoutId parentId = layout.parent(); |
122 | return layoutMap.values().stream() | 123 | return layoutMap.values().stream() |
124 | + // all layouts who are NOT me and who share my parent... | ||
123 | .filter(l -> !Objects.equals(l.id(), layoutId) && | 125 | .filter(l -> !Objects.equals(l.id(), layoutId) && |
124 | Objects.equals(l.parent(), parentId)) | 126 | Objects.equals(l.parent(), parentId)) |
125 | .collect(Collectors.toSet()); | 127 | .collect(Collectors.toSet()); |
... | @@ -129,7 +131,7 @@ public class UiTopoLayoutManager implements UiTopoLayoutService { | ... | @@ -129,7 +131,7 @@ public class UiTopoLayoutManager implements UiTopoLayoutService { |
129 | public Set<UiTopoLayout> getChildren(UiTopoLayoutId layoutId) { | 131 | public Set<UiTopoLayout> getChildren(UiTopoLayoutId layoutId) { |
130 | checkNotNull(layoutId, ID_NULL); | 132 | checkNotNull(layoutId, ID_NULL); |
131 | return layoutMap.values().stream() | 133 | return layoutMap.values().stream() |
132 | - .filter(l -> Objects.equals(l.parent(), layoutId)) | 134 | + .filter(l -> !l.isRoot() && Objects.equals(l.parent(), layoutId)) |
133 | .collect(Collectors.toSet()); | 135 | .collect(Collectors.toSet()); |
134 | } | 136 | } |
135 | 137 | ... | ... |
... | @@ -23,6 +23,7 @@ import org.onosproject.ui.impl.topo.model.UiModelEvent; | ... | @@ -23,6 +23,7 @@ import org.onosproject.ui.impl.topo.model.UiModelEvent; |
23 | import org.onosproject.ui.impl.topo.model.UiModelListener; | 23 | import org.onosproject.ui.impl.topo.model.UiModelListener; |
24 | import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel; | 24 | import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel; |
25 | import org.onosproject.ui.model.topo.UiClusterMember; | 25 | import org.onosproject.ui.model.topo.UiClusterMember; |
26 | +import org.onosproject.ui.model.topo.UiNode; | ||
26 | import org.onosproject.ui.model.topo.UiRegion; | 27 | import org.onosproject.ui.model.topo.UiRegion; |
27 | import org.onosproject.ui.model.topo.UiTopoLayout; | 28 | import org.onosproject.ui.model.topo.UiTopoLayout; |
28 | import org.slf4j.Logger; | 29 | import org.slf4j.Logger; |
... | @@ -170,17 +171,32 @@ public class UiTopoSession implements UiModelListener { | ... | @@ -170,17 +171,32 @@ public class UiTopoSession implements UiModelListener { |
170 | } | 171 | } |
171 | 172 | ||
172 | /** | 173 | /** |
173 | - * Returns the regions that are "peers" to this region. That is, based on | 174 | + * Returns the regions/devices that are "peers" to this region. That is, |
174 | - * the layout the user is viewing, all the regions that are associated with | 175 | + * based on the layout the user is viewing, all the regions/devices that |
175 | - * layouts that share the same parent layout as this layout. | 176 | + * are associated with layouts that share the same parent layout as this |
177 | + * layout, AND that are linked to an element within this region. | ||
176 | * | 178 | * |
177 | * @param layout the layout being viewed | 179 | * @param layout the layout being viewed |
178 | - * @return all regions that are "siblings" to this layout's region | 180 | + * @return all regions/devices that are "siblings" to this layout's region |
179 | */ | 181 | */ |
180 | - public Set<UiRegion> getPeerRegions(UiTopoLayout layout) { | 182 | + public Set<UiNode> getPeerNodes(UiTopoLayout layout) { |
181 | - Set<UiTopoLayout> peerLayouts = layoutService.getPeers(layout.id()); | 183 | + Set<UiNode> peers = new HashSet<>(); |
182 | - Set<UiRegion> peers = new HashSet<>(); | 184 | + |
183 | - peerLayouts.forEach(l -> peers.add(sharedModel.getRegion(l.regionId()))); | 185 | + // first, get the peer regions |
186 | + Set<UiTopoLayout> peerLayouts = layoutService.getPeerLayouts(layout.id()); | ||
187 | + peerLayouts.forEach(l -> { | ||
188 | + RegionId peerRegion = l.regionId(); | ||
189 | + peers.add(sharedModel.getRegion(peerRegion)); | ||
190 | + }); | ||
191 | + | ||
192 | + // now add the devices that reside in the parent region | ||
193 | + if (!layout.isRoot()) { | ||
194 | + UiTopoLayout parentLayout = layoutService.getLayout(layout.parent()); | ||
195 | + getRegion(parentLayout).devices().forEach(peers::add); | ||
196 | + } | ||
197 | + | ||
198 | + // TODO: Finally, filter out regions / devices that are not connected | ||
199 | + // directly to this region by an implicit link | ||
184 | return peers; | 200 | return peers; |
185 | } | 201 | } |
186 | 202 | ... | ... |
... | @@ -25,3 +25,28 @@ | ... | @@ -25,3 +25,28 @@ |
25 | /* prevents the little cut/copy/paste square that would appear on iPad */ | 25 | /* prevents the little cut/copy/paste square that would appear on iPad */ |
26 | -webkit-user-select: none; | 26 | -webkit-user-select: none; |
27 | } | 27 | } |
28 | + | ||
29 | +/* -- TEMPORARY CSS (to be deleted) -- */ | ||
30 | +#topo2tmp div { | ||
31 | + padding: 8px 24px; | ||
32 | + margin: 8px; | ||
33 | + background-color: #ddddff; | ||
34 | +} | ||
35 | +#topo2tmp div div { | ||
36 | + padding: 4px 10px; | ||
37 | +} | ||
38 | + | ||
39 | +#topo2tmp h4 { | ||
40 | + margin: 0 | ||
41 | +} | ||
42 | +#topo2tmp p { | ||
43 | + margin: 0 | ||
44 | +} | ||
45 | +#topo2tmp .nav-me:hover { | ||
46 | + background-color: #bbbbdd; | ||
47 | +} | ||
48 | +#topo2tmp .nav-me { | ||
49 | + font-weight: bold; | ||
50 | + text-decoration: underline; | ||
51 | + cursor: pointer; | ||
52 | +} | ... | ... |
1 | <!-- Topology View partial HTML --> | 1 | <!-- Topology View partial HTML --> |
2 | <div id="ov-topo2"> | 2 | <div id="ov-topo2"> |
3 | + <div id="topo2tmp"> | ||
4 | + <div class="parentRegion"> | ||
5 | + Parent Region: <span> - </span> | ||
6 | + </div> | ||
7 | + <div class="thisRegion"> | ||
8 | + This Region: <span> - </span> | ||
9 | + </div> | ||
10 | + <div class="subRegions"> | ||
11 | + <h4>Subregions</h4> | ||
12 | + <div></div> | ||
13 | + </div> | ||
14 | + <div class="devices"> | ||
15 | + <h4>Devices</h4> | ||
16 | + <div></div> | ||
17 | + </div> | ||
18 | + <div class="hosts"> | ||
19 | + <h4>Hosts</h4> | ||
20 | + <div></div> | ||
21 | + </div> | ||
22 | + <div class="links"> | ||
23 | + <h4>Links</h4> | ||
24 | + <div></div> | ||
25 | + </div> | ||
26 | + <div class="peers"> | ||
27 | + <h4>Peers</h4> | ||
28 | + <div></div> | ||
29 | + </div> | ||
30 | + </div> | ||
31 | + | ||
32 | + <!-- Below here is good; Above here is temporary, for debugging --> | ||
33 | + | ||
3 | <svg viewBox="0 0 1000 1000" | 34 | <svg viewBox="0 0 1000 1000" |
4 | resize offset-height="56" offset-width="12" | 35 | resize offset-height="56" offset-width="12" |
5 | notifier="notifyResize()"> | 36 | notifier="notifyResize()"> | ... | ... |
... | @@ -42,6 +42,7 @@ | ... | @@ -42,6 +42,7 @@ |
42 | topo2AllInstances: t2fs, | 42 | topo2AllInstances: t2fs, |
43 | topo2CurrentLayout: t2fs, | 43 | topo2CurrentLayout: t2fs, |
44 | topo2CurrentRegion: t2fs, | 44 | topo2CurrentRegion: t2fs, |
45 | + topo2PeerRegions: t2fs, | ||
45 | topo2StartDone: t2fs | 46 | topo2StartDone: t2fs |
46 | 47 | ||
47 | // Add further event names / module references as needed | 48 | // Add further event names / module references as needed | ... | ... |
... | @@ -35,10 +35,79 @@ | ... | @@ -35,10 +35,79 @@ |
35 | $log.debug('Destroy topo force layout'); | 35 | $log.debug('Destroy topo force layout'); |
36 | } | 36 | } |
37 | 37 | ||
38 | + // ========================== Temporary Code (to be deleted later) | ||
39 | + | ||
40 | + function request(dir, rid) { | ||
41 | + wss.sendEvent('topo2navRegion', { | ||
42 | + dir: dir, | ||
43 | + rid: rid | ||
44 | + }); | ||
45 | + } | ||
46 | + | ||
47 | + function doTmpCurrentLayout(data) { | ||
48 | + var topdiv = d3.select('#topo2tmp'); | ||
49 | + var parentRegion = data.parent; | ||
50 | + var span = topdiv.select('.parentRegion').select('span'); | ||
51 | + span.text(parentRegion || '[no parent]'); | ||
52 | + span.classed('nav-me', !!parentRegion); | ||
53 | + } | ||
54 | + | ||
55 | + function doTmpCurrentRegion(data) { | ||
56 | + var topdiv = d3.select('#topo2tmp'); | ||
57 | + var span = topdiv.select('.thisRegion').select('span'); | ||
58 | + var div; | ||
59 | + | ||
60 | + span.text(data.id); | ||
61 | + | ||
62 | + div = topdiv.select('.subRegions').select('div'); | ||
63 | + data.subregions.forEach(function (r) { | ||
64 | + | ||
65 | + function nav() { | ||
66 | + request('down', r.id); | ||
67 | + } | ||
68 | + | ||
69 | + div.append('p') | ||
70 | + .classed('nav-me', true) | ||
71 | + .text(r.id) | ||
72 | + .on('click', nav); | ||
73 | + }); | ||
74 | + | ||
75 | + div = topdiv.select('.devices').select('div'); | ||
76 | + data.layerOrder.forEach(function (tag, idx) { | ||
77 | + var devs = data.devices[idx]; | ||
78 | + devs.forEach(function (d) { | ||
79 | + div.append('p') | ||
80 | + .text('[' + tag + '] ' + d.id); | ||
81 | + }); | ||
82 | + | ||
83 | + }); | ||
84 | + | ||
85 | + div = topdiv.select('.hosts').select('div'); | ||
86 | + data.layerOrder.forEach(function (tag, idx) { | ||
87 | + var hosts = data.hosts[idx]; | ||
88 | + hosts.forEach(function (h) { | ||
89 | + div.append('p') | ||
90 | + .text('[' + tag + '] ' + h.id); | ||
91 | + }); | ||
92 | + }); | ||
93 | + | ||
94 | + div = topdiv.select('.links').select('div'); | ||
95 | + var links = data.links; | ||
96 | + links.forEach(function (lnk) { | ||
97 | + div.append('p') | ||
98 | + .text(lnk.id); | ||
99 | + }); | ||
100 | + } | ||
101 | + | ||
102 | + function doTmpPeerRegions(data) { | ||
103 | + | ||
104 | + } | ||
105 | + | ||
38 | // ========================== Event Handlers | 106 | // ========================== Event Handlers |
39 | 107 | ||
40 | function allInstances(data) { | 108 | function allInstances(data) { |
41 | $log.debug('>> topo2AllInstances event:', data) | 109 | $log.debug('>> topo2AllInstances event:', data) |
110 | + doTmpCurrentLayout(data); | ||
42 | } | 111 | } |
43 | 112 | ||
44 | function currentLayout(data) { | 113 | function currentLayout(data) { |
... | @@ -47,6 +116,16 @@ | ... | @@ -47,6 +116,16 @@ |
47 | 116 | ||
48 | function currentRegion(data) { | 117 | function currentRegion(data) { |
49 | $log.debug('>> topo2CurrentRegion event:', data) | 118 | $log.debug('>> topo2CurrentRegion event:', data) |
119 | + doTmpCurrentRegion(data); | ||
120 | + } | ||
121 | + | ||
122 | + function topo2PeerRegions(data) { | ||
123 | + $log.debug('>> topo2PeerRegions event:', data) | ||
124 | + doTmpPeerRegions(data); | ||
125 | + } | ||
126 | + | ||
127 | + function topo2PeerRegions(data) { | ||
128 | + $log.debug('>> topo2PeerRegions event:', data) | ||
50 | } | 129 | } |
51 | 130 | ||
52 | function startDone(data) { | 131 | function startDone(data) { |
... | @@ -69,6 +148,7 @@ | ... | @@ -69,6 +148,7 @@ |
69 | topo2AllInstances: allInstances, | 148 | topo2AllInstances: allInstances, |
70 | topo2CurrentLayout: currentLayout, | 149 | topo2CurrentLayout: currentLayout, |
71 | topo2CurrentRegion: currentRegion, | 150 | topo2CurrentRegion: currentRegion, |
151 | + topo2PeerRegions: topo2PeerRegions, | ||
72 | topo2StartDone: startDone | 152 | topo2StartDone: startDone |
73 | }; | 153 | }; |
74 | }]); | 154 | }]); | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
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 | + | ||
17 | +/* | ||
18 | + * Copyright 2016-present Open Networking Laboratory | ||
19 | + * | ||
20 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
21 | + * you may not use this file except in compliance with the License. | ||
22 | + * You may obtain a copy of the License at | ||
23 | + * | ||
24 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
25 | + * | ||
26 | + * Unless required by applicable law or agreed to in writing, software | ||
27 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
28 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
29 | + * See the License for the specific language governing permissions and | ||
30 | + * limitations under the License. | ||
31 | + */ | ||
32 | + | ||
33 | + | ||
34 | +/* | ||
35 | + ONOS GUI -- Topology View (theme) -- CSS file | ||
36 | + */ | ||
37 | + | ||
38 | +/* --- Base SVG Layer --- */ | ||
39 | + | ||
40 | +#ov-topoX svg { | ||
41 | + /*background-color: #f4f4f4;*/ | ||
42 | + background-color: goldenrod; /* just for testing */ | ||
43 | +} | ||
44 | + | ||
45 | +/* --- "No Devices" Layer --- */ | ||
46 | + | ||
47 | +#ov-topoX svg .noDevsBird { | ||
48 | + fill: #db7773; | ||
49 | +} | ||
50 | + | ||
51 | +#ov-topoX svg #topoX-noDevsLayer text { | ||
52 | + fill: #7e9aa8; | ||
53 | +} | ||
54 | + | ||
55 | +/* --- Topo Map --- */ | ||
56 | + | ||
57 | +#ov-topoX svg #topoX-map { | ||
58 | + stroke-width: 2px; | ||
59 | + stroke: #f4f4f4; | ||
60 | + fill: #e5e5e6; | ||
61 | +} | ||
62 | + |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
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 | + | ||
17 | + | ||
18 | +/* | ||
19 | + ONOS GUI -- Topology View (layout) -- CSS file | ||
20 | + */ | ||
21 | + | ||
22 | +/* --- Base SVG Layer --- */ | ||
23 | + | ||
24 | +#ov-topoX svg { | ||
25 | + /* prevents the little cut/copy/paste square that would appear on iPad */ | ||
26 | + -webkit-user-select: none; | ||
27 | +} | ||
28 | + | ||
29 | +/* -- TEMPORARY CSS (to be deleted) -- */ | ||
30 | +#topoXtmp div { | ||
31 | + padding: 8px 24px; | ||
32 | + margin: 8px; | ||
33 | + background-color: #ddddff; | ||
34 | +} | ||
35 | +#topoXtmp div div { | ||
36 | + padding: 4px 10px; | ||
37 | +} | ||
38 | + | ||
39 | +#topoXtmp h4 { | ||
40 | + margin: 0 | ||
41 | +} | ||
42 | +#topoXtmp p { | ||
43 | + margin: 0 | ||
44 | +} | ||
45 | +#topoXtmp .nav-me:hover { | ||
46 | + background-color: #bbbbdd; | ||
47 | +} | ||
48 | +#topoXtmp .nav-me { | ||
49 | + font-weight: bold; | ||
50 | + text-decoration: underline; | ||
51 | + cursor: pointer; | ||
52 | +} |
1 | +<!-- | ||
2 | + ~ Copyright 2016-present Open Networking Laboratory | ||
3 | + ~ | ||
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 | + | ||
17 | +<!-- Topology View partial HTML --> | ||
18 | +<div id="ov-topoX"> | ||
19 | + <div id="topoXtmp"> | ||
20 | + <div class="parentRegion"> | ||
21 | + Parent Region: <span> - </span> | ||
22 | + </div> | ||
23 | + <div class="thisRegion"> | ||
24 | + This Region: <span> - </span> | ||
25 | + </div> | ||
26 | + <div class="subRegions"> | ||
27 | + <h4>Subregions</h4> | ||
28 | + <div></div> | ||
29 | + </div> | ||
30 | + <div class="devices"> | ||
31 | + <h4>Devices</h4> | ||
32 | + <div></div> | ||
33 | + </div> | ||
34 | + <div class="hosts"> | ||
35 | + <h4>Hosts</h4> | ||
36 | + <div></div> | ||
37 | + </div> | ||
38 | + <div class="links"> | ||
39 | + <h4>Links</h4> | ||
40 | + <div></div> | ||
41 | + </div> | ||
42 | + <div class="peers"> | ||
43 | + <h4>Peers</h4> | ||
44 | + <div></div> | ||
45 | + </div> | ||
46 | + </div> | ||
47 | +</div> |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
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 | + | ||
17 | +/* | ||
18 | + * Copyright 2016-present Open Networking Laboratory | ||
19 | + * | ||
20 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
21 | + * you may not use this file except in compliance with the License. | ||
22 | + * You may obtain a copy of the License at | ||
23 | + * | ||
24 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
25 | + * | ||
26 | + * Unless required by applicable law or agreed to in writing, software | ||
27 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
28 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
29 | + * See the License for the specific language governing permissions and | ||
30 | + * limitations under the License. | ||
31 | + */ | ||
32 | + | ||
33 | +/* | ||
34 | + ONOS GUI -- Topology View Module | ||
35 | + | ||
36 | + NOTE: currently under development to support Regions. | ||
37 | + */ | ||
38 | + | ||
39 | +(function () { | ||
40 | + 'use strict'; | ||
41 | + | ||
42 | + // references to injected services | ||
43 | + var $scope, $log, $loc, | ||
44 | + fs, mast, ks, zs, | ||
45 | + gs, ms, sus, flash, | ||
46 | + wss, ps, th, | ||
47 | + tXes, tXfs; | ||
48 | + | ||
49 | + // DOM elements | ||
50 | + var ovtopoX, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; | ||
51 | + | ||
52 | + // Internal state | ||
53 | + var zoomer, actionMap; | ||
54 | + | ||
55 | + | ||
56 | + // === Helper Functions | ||
57 | + | ||
58 | + // callback invoked when the SVG view has been resized.. | ||
59 | + function svgResized(s) { | ||
60 | + $log.debug("topoX view resized", s); | ||
61 | + } | ||
62 | + | ||
63 | + function setUpKeys(overlayKeys) { | ||
64 | + $log.debug('topoX: set up keys....'); | ||
65 | + } | ||
66 | + | ||
67 | + // === Controller Definition ----------------------------------------- | ||
68 | + | ||
69 | + angular.module('ovTopoX', ['onosUtil', 'onosSvg', 'onosRemote']) | ||
70 | + .controller('OvTopoXCtrl', | ||
71 | + ['$scope', '$log', '$location', | ||
72 | + 'FnService', 'MastService', 'KeyService', 'ZoomService', | ||
73 | + 'GlyphService', 'MapService', 'SvgUtilService', 'FlashService', | ||
74 | + 'WebSocketService', 'PrefsService', 'ThemeService', | ||
75 | + 'TopoXEventService', 'TopoXForceService', | ||
76 | + | ||
77 | + function (_$scope_, _$log_, _$loc_, | ||
78 | + _fs_, _mast_, _ks_, _zs_, | ||
79 | + _gs_, _ms_, _sus_, _flash_, | ||
80 | + _wss_, _ps_, _th_, | ||
81 | + _tXes_, _tXfs_) { | ||
82 | + | ||
83 | + var params = _$loc_.search(), | ||
84 | + projection, | ||
85 | + dim, | ||
86 | + wh, | ||
87 | + uplink = { | ||
88 | + // provides function calls back into this space | ||
89 | + // showNoDevs: showNoDevs, | ||
90 | + // projection: function () { return projection; }, | ||
91 | + // zoomLayer: function () { return zoomLayer; }, | ||
92 | + // zoomer: function () { return zoomer; }, | ||
93 | + // opacifyMap: opacifyMap, | ||
94 | + // topoStartDone: topoStartDone | ||
95 | + }; | ||
96 | + | ||
97 | + $scope = _$scope_; | ||
98 | + $log = _$log_; | ||
99 | + $loc = _$loc_; | ||
100 | + | ||
101 | + fs = _fs_; | ||
102 | + mast = _mast_; | ||
103 | + ks = _ks_; | ||
104 | + zs = _zs_; | ||
105 | + | ||
106 | + gs = _gs_; | ||
107 | + ms = _ms_; | ||
108 | + sus = _sus_; | ||
109 | + flash = _flash_; | ||
110 | + | ||
111 | + wss = _wss_; | ||
112 | + ps = _ps_; | ||
113 | + th = _th_; | ||
114 | + | ||
115 | + tXes = _tXes_; | ||
116 | + tXfs = _tXfs_; | ||
117 | + | ||
118 | + // capture selected intent parameters (if they are set in the | ||
119 | + // query string) so that the traffic overlay can highlight | ||
120 | + // the path for that intent | ||
121 | + if (params.intentKey && params.intentAppId && params.intentAppName) { | ||
122 | + $scope.intentData = { | ||
123 | + key: params.intentKey, | ||
124 | + appId: params.intentAppId, | ||
125 | + appName: params.intentAppName | ||
126 | + }; | ||
127 | + } | ||
128 | + | ||
129 | + $scope.notifyResize = function () { | ||
130 | + svgResized(fs.windowSize(mast.mastHeight())); | ||
131 | + }; | ||
132 | + | ||
133 | + // Cleanup on destroyed scope.. | ||
134 | + $scope.$on('$destroy', function () { | ||
135 | + $log.log('OvTopoXCtrl is saying Buh-Bye!'); | ||
136 | + tXes.stop(); | ||
137 | + ks.unbindKeys(); | ||
138 | + tXfs.destroy(); | ||
139 | + }); | ||
140 | + | ||
141 | + // svg layer and initialization of components | ||
142 | + ovtopoX = d3.select('#ov-topoX'); | ||
143 | + svg = ovtopoX.select('svg'); | ||
144 | + // set the svg size to match that of the window, less the masthead | ||
145 | + wh = fs.windowSize(mast.mastHeight()); | ||
146 | + $log.debug('setting topo SVG size to', wh); | ||
147 | + svg.attr(wh); | ||
148 | + dim = [wh.width, wh.height]; | ||
149 | + | ||
150 | + | ||
151 | + // set up our keyboard shortcut bindings | ||
152 | + setUpKeys(); | ||
153 | + | ||
154 | + // make sure we can respond to topology events from the server | ||
155 | + tXes.bindHandlers(); | ||
156 | + | ||
157 | + // initialize the force layout, ready to render the topology | ||
158 | + tXfs.init(); | ||
159 | + | ||
160 | + | ||
161 | + // =-=-=-=-=-=-=-=- | ||
162 | + // TODO: in future, we will load background map data | ||
163 | + // asynchronously (hence the promise) and then chain off | ||
164 | + // there to send the topoXstart event to the server. | ||
165 | + // For now, we'll send the event inline... | ||
166 | + tXes.start(); | ||
167 | + | ||
168 | + | ||
169 | + // === ORIGINAL CODE === | ||
170 | + | ||
171 | + // setUpKeys(); | ||
172 | + // setUpToolbar(); | ||
173 | + // setUpDefs(); | ||
174 | + // setUpZoom(); | ||
175 | + // setUpNoDevs(); | ||
176 | + /* | ||
177 | + setUpMap().then( | ||
178 | + function (proj) { | ||
179 | + var z = ps.getPrefs('topo_zoom', { tx:0, ty:0, sc:1 }); | ||
180 | + zoomer.panZoom([z.tx, z.ty], z.sc); | ||
181 | + $log.debug('** Zoom restored:', z); | ||
182 | + | ||
183 | + projection = proj; | ||
184 | + $log.debug('** We installed the projection:', proj); | ||
185 | + flash.enable(false); | ||
186 | + toggleMap(prefsState.bg); | ||
187 | + flash.enable(true); | ||
188 | + mapShader(true); | ||
189 | + | ||
190 | + // now we have the map projection, we are ready for | ||
191 | + // the server to send us device/host data... | ||
192 | + tes.start(); | ||
193 | + // need to do the following so we immediately get | ||
194 | + // the summary panel data back from the server | ||
195 | + restoreSummaryFromPrefs(); | ||
196 | + } | ||
197 | + ); | ||
198 | + */ | ||
199 | + // tes.bindHandlers(); | ||
200 | + // setUpSprites(); | ||
201 | + | ||
202 | + // forceG = zoomLayer.append('g').attr('id', 'topo-force'); | ||
203 | + // tfs.initForce(svg, forceG, uplink, dim); | ||
204 | + // tis.initInst({ showMastership: tfs.showMastership }); | ||
205 | + // tps.initPanels(); | ||
206 | + | ||
207 | + // restoreConfigFromPrefs(); | ||
208 | + // ttbs.setDefaultOverlay(prefsState.ovidx); | ||
209 | + | ||
210 | + // $log.debug('registered overlays...', tov.list()); | ||
211 | + | ||
212 | + $log.log('OvTopoXCtrl has been created'); | ||
213 | + }]); | ||
214 | +}()); |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
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 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Topology Event Module. | ||
19 | + | ||
20 | + Defines the conduit between the client and the server: | ||
21 | + - provides a clean API for sending events to the server | ||
22 | + - dispatches incoming events from the server to the appropriate sub-module | ||
23 | + | ||
24 | + */ | ||
25 | + | ||
26 | +(function () { | ||
27 | + 'use strict'; | ||
28 | + | ||
29 | + // injected refs | ||
30 | + var $log, wss, tXfs; | ||
31 | + | ||
32 | + // internal state | ||
33 | + var handlerMap, | ||
34 | + openListener; | ||
35 | + | ||
36 | + // ========================== Helper Functions | ||
37 | + | ||
38 | + function createHandlerMap() { | ||
39 | + handlerMap = { | ||
40 | + topo2AllInstances: tXfs, | ||
41 | + topo2CurrentLayout: tXfs, | ||
42 | + topo2CurrentRegion: tXfs, | ||
43 | + topo2PeerRegions: tXfs, | ||
44 | + topo2StartDone: tXfs | ||
45 | + | ||
46 | + // Add further event names / module references as needed | ||
47 | + }; | ||
48 | + } | ||
49 | + | ||
50 | + function wsOpen(host, url) { | ||
51 | + $log.debug('topoXEvent: WSopen - cluster node:', host, 'URL:', url); | ||
52 | + // tell the server we are ready to receive topo events | ||
53 | + wss.sendEvent('topo2Start'); | ||
54 | + } | ||
55 | + | ||
56 | + // bind our event handlers to the web socket service, so that our | ||
57 | + // callbacks get invoked for incoming events | ||
58 | + function bindHandlers() { | ||
59 | + wss.bindHandlers(handlerMap); | ||
60 | + $log.debug('topoX event handlers bound'); | ||
61 | + } | ||
62 | + | ||
63 | + // tell the server we are ready to receive topology events | ||
64 | + function start() { | ||
65 | + // in case we fail over to a new server, | ||
66 | + // listen for wsock-open events | ||
67 | + openListener = wss.addOpenListener(wsOpen); | ||
68 | + wss.sendEvent('topo2Start'); | ||
69 | + $log.debug('topoX comms started'); | ||
70 | + } | ||
71 | + | ||
72 | + // tell the server we no longer wish to receive topology events | ||
73 | + function stop() { | ||
74 | + wss.sendEvent('topo2Stop'); | ||
75 | + wss.unbindHandlers(handlerMap); | ||
76 | + wss.removeOpenListener(openListener); | ||
77 | + openListener = null; | ||
78 | + $log.debug('topoX comms stopped'); | ||
79 | + } | ||
80 | + | ||
81 | + // ========================== Main Service Definition | ||
82 | + | ||
83 | + angular.module('ovTopoX') | ||
84 | + .factory('TopoXEventService', | ||
85 | + ['$log', 'WebSocketService', 'TopoXForceService', | ||
86 | + | ||
87 | + function (_$log_, _wss_, _tXfs_) { | ||
88 | + $log = _$log_; | ||
89 | + wss = _wss_; | ||
90 | + tXfs = _tXfs_; | ||
91 | + | ||
92 | + // deferred creation of handler map, so module references are good | ||
93 | + createHandlerMap(); | ||
94 | + | ||
95 | + return { | ||
96 | + bindHandlers: bindHandlers, | ||
97 | + start: start, | ||
98 | + stop: stop | ||
99 | + }; | ||
100 | + }]); | ||
101 | +}()); |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
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 | + | ||
17 | +/* | ||
18 | + ONOS GUI -- Topology Force Module. | ||
19 | + Visualization of the topology in an SVG layer, using a D3 Force Layout. | ||
20 | + */ | ||
21 | + | ||
22 | +(function () { | ||
23 | + 'use strict'; | ||
24 | + | ||
25 | + // injected refs | ||
26 | + var $log, wss; | ||
27 | + | ||
28 | + // ========================== Helper Functions | ||
29 | + | ||
30 | + function init() { | ||
31 | + $log.debug('Initialize topo force layout'); | ||
32 | + } | ||
33 | + | ||
34 | + function destroy() { | ||
35 | + $log.debug('Destroy topo force layout'); | ||
36 | + } | ||
37 | + | ||
38 | + // ========================== Temporary Code (to be deleted later) | ||
39 | + | ||
40 | + function request(dir, rid) { | ||
41 | + wss.sendEvent('topo2navRegion', { | ||
42 | + dir: dir, | ||
43 | + rid: rid | ||
44 | + }); | ||
45 | + } | ||
46 | + | ||
47 | + function doTmpCurrentLayout(data) { | ||
48 | + var topdiv = d3.select('#topoXtmp'); | ||
49 | + var parentRegion = data.parent; | ||
50 | + var span = topdiv.select('.parentRegion').select('span'); | ||
51 | + span.text(parentRegion || '[no parent]'); | ||
52 | + span.classed('nav-me', !!parentRegion); | ||
53 | + } | ||
54 | + | ||
55 | + function doTmpCurrentRegion(data) { | ||
56 | + var topdiv = d3.select('#topoXtmp'); | ||
57 | + var span = topdiv.select('.thisRegion').select('span'); | ||
58 | + var div; | ||
59 | + | ||
60 | + span.text(data.id); | ||
61 | + | ||
62 | + div = topdiv.select('.subRegions').select('div'); | ||
63 | + data.subregions.forEach(function (r) { | ||
64 | + | ||
65 | + function nav() { | ||
66 | + request('down', r.id); | ||
67 | + } | ||
68 | + | ||
69 | + div.append('p') | ||
70 | + .classed('nav-me', true) | ||
71 | + .text(r.id) | ||
72 | + .on('click', nav); | ||
73 | + }); | ||
74 | + | ||
75 | + div = topdiv.select('.devices').select('div'); | ||
76 | + data.layerOrder.forEach(function (tag, idx) { | ||
77 | + var devs = data.devices[idx]; | ||
78 | + devs.forEach(function (d) { | ||
79 | + div.append('p') | ||
80 | + .text('[' + tag + '] ' + d.id); | ||
81 | + }); | ||
82 | + | ||
83 | + }); | ||
84 | + | ||
85 | + div = topdiv.select('.hosts').select('div'); | ||
86 | + data.layerOrder.forEach(function (tag, idx) { | ||
87 | + var hosts = data.hosts[idx]; | ||
88 | + hosts.forEach(function (h) { | ||
89 | + div.append('p') | ||
90 | + .text('[' + tag + '] ' + h.id); | ||
91 | + }); | ||
92 | + }); | ||
93 | + | ||
94 | + div = topdiv.select('.links').select('div'); | ||
95 | + var links = data.links; | ||
96 | + links.forEach(function (lnk) { | ||
97 | + div.append('p') | ||
98 | + .text(lnk.id); | ||
99 | + }); | ||
100 | + } | ||
101 | + | ||
102 | + function doTmpPeerRegions(data) { | ||
103 | + | ||
104 | + } | ||
105 | + | ||
106 | + // ========================== Event Handlers | ||
107 | + | ||
108 | + function allInstances(data) { | ||
109 | + $log.debug('>> topo2AllInstances event:', data) | ||
110 | + doTmpCurrentLayout(data); | ||
111 | + } | ||
112 | + | ||
113 | + function currentLayout(data) { | ||
114 | + $log.debug('>> topo2CurrentLayout event:', data) | ||
115 | + } | ||
116 | + | ||
117 | + function currentRegion(data) { | ||
118 | + $log.debug('>> topo2CurrentRegion event:', data) | ||
119 | + doTmpCurrentRegion(data); | ||
120 | + } | ||
121 | + | ||
122 | + function peerRegions(data) { | ||
123 | + $log.debug('>> topo2PeerRegions event:', data) | ||
124 | + doTmpPeerRegions(data); | ||
125 | + } | ||
126 | + | ||
127 | + function startDone(data) { | ||
128 | + $log.debug('>> topo2StartDone event:', data) | ||
129 | + } | ||
130 | + | ||
131 | + // ========================== Main Service Definition | ||
132 | + | ||
133 | + angular.module('ovTopoX') | ||
134 | + .factory('TopoXForceService', | ||
135 | + ['$log', 'WebSocketService', | ||
136 | + | ||
137 | + function (_$log_, _wss_) { | ||
138 | + $log = _$log_; | ||
139 | + wss = _wss_; | ||
140 | + | ||
141 | + return { | ||
142 | + init: init, | ||
143 | + destroy: destroy, | ||
144 | + topo2AllInstances: allInstances, | ||
145 | + topo2CurrentLayout: currentLayout, | ||
146 | + topo2CurrentRegion: currentRegion, | ||
147 | + topo2PeerRegions: peerRegions, | ||
148 | + topo2StartDone: startDone | ||
149 | + }; | ||
150 | + }]); | ||
151 | +}()); |
... | @@ -133,6 +133,12 @@ | ... | @@ -133,6 +133,12 @@ |
133 | <link rel="stylesheet" href="app/view/topo2/topo2.css"> | 133 | <link rel="stylesheet" href="app/view/topo2/topo2.css"> |
134 | <link rel="stylesheet" href="app/view/topo2/topo2-theme.css"> | 134 | <link rel="stylesheet" href="app/view/topo2/topo2-theme.css"> |
135 | 135 | ||
136 | + <script src="app/view/topoX/topoX.js"></script> | ||
137 | + <script src="app/view/topoX/topoXEvent.js"></script> | ||
138 | + <script src="app/view/topoX/topoXForce.js"></script> | ||
139 | + <link rel="stylesheet" href="app/view/topoX/topoX.css"> | ||
140 | + <link rel="stylesheet" href="app/view/topoX/topoX-theme.css"> | ||
141 | + | ||
136 | <!-- Builtin views javascript. --> | 142 | <!-- Builtin views javascript. --> |
137 | <script src="app/view/topo/topo.js"></script> | 143 | <script src="app/view/topo/topo.js"></script> |
138 | <script src="app/view/topo/topoD3.js"></script> | 144 | <script src="app/view/topo/topoD3.js"></script> | ... | ... |
... | @@ -4,9 +4,11 @@ | ... | @@ -4,9 +4,11 @@ |
4 | "id": "<null-region>", | 4 | "id": "<null-region>", |
5 | "subregions": [{ | 5 | "subregions": [{ |
6 | "id": "r2", | 6 | "id": "r2", |
7 | + "nodeType":"region", | ||
7 | "nDevs": 2 | 8 | "nDevs": 2 |
8 | }, { | 9 | }, { |
9 | "id": "r1", | 10 | "id": "r1", |
11 | + "nodeType":"region", | ||
10 | "nDevs": 3 | 12 | "nDevs": 3 |
11 | }], | 13 | }], |
12 | "devices": [ | 14 | "devices": [ |
... | @@ -14,6 +16,7 @@ | ... | @@ -14,6 +16,7 @@ |
14 | [], | 16 | [], |
15 | [{ | 17 | [{ |
16 | "id": "null:0000000000000001", | 18 | "id": "null:0000000000000001", |
19 | + "nodeType":"device", | ||
17 | "type": "switch", | 20 | "type": "switch", |
18 | "online": false, | 21 | "online": false, |
19 | "master": "", | 22 | "master": "", | ... | ... |
-
Please register or login to post a comment