blob: 708fd18dfd014f3014bcc75acaa404ce455e95db [file] [log] [blame]
Simon Hunt5f6dbf82016-03-30 08:53:33 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Simon Hunt5f6dbf82016-03-30 08:53:33 -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.model.topo;
18
Simon Hunt338a3b42016-04-14 09:43:52 -070019import org.onosproject.cluster.NodeId;
Simon Huntc0f20c12016-05-09 09:30:20 -070020import org.onosproject.net.DeviceId;
21import org.onosproject.net.HostId;
22import org.onosproject.net.region.RegionId;
Simon Hunt23fb1352016-04-11 12:15:19 -070023import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
Simon Huntd5b96732016-07-08 13:22:27 -070026import java.util.ArrayList;
27import java.util.Collections;
28import java.util.Comparator;
Simon Huntc0f20c12016-05-09 09:30:20 -070029import java.util.HashMap;
30import java.util.HashSet;
Simon Huntd5b96732016-07-08 13:22:27 -070031import java.util.List;
Simon Huntc0f20c12016-05-09 09:30:20 -070032import java.util.Map;
Simon Hunt23fb1352016-04-11 12:15:19 -070033import java.util.Set;
Simon Huntc0f20c12016-05-09 09:30:20 -070034
35import static com.google.common.base.MoreObjects.toStringHelper;
Simon Hunt23fb1352016-04-11 12:15:19 -070036
Simon Hunt5f6dbf82016-03-30 08:53:33 -070037/**
38 * Represents the overall network topology.
39 */
Simon Huntcda9c032016-04-11 10:32:54 -070040public class UiTopology extends UiElement {
Simon Hunt23fb1352016-04-11 12:15:19 -070041
Simon Hunt58a0dd02016-05-17 11:54:23 -070042 private static final String INDENT_1 = " ";
43 private static final String INDENT_2 = " ";
44 private static final String EOL = String.format("%n");
45
Simon Huntc0f20c12016-05-09 09:30:20 -070046 private static final String E_UNMAPPED =
47 "Attempting to retrieve unmapped {}: {}";
48
Simon Hunt642bc452016-05-04 19:34:45 -070049 private static final String DEFAULT_TOPOLOGY_ID = "TOPOLOGY-0";
50
Simon Hunt23fb1352016-04-11 12:15:19 -070051 private static final Logger log = LoggerFactory.getLogger(UiTopology.class);
52
Simon Huntd5b96732016-07-08 13:22:27 -070053 private static final Comparator<UiClusterMember> CLUSTER_MEMBER_COMPARATOR =
54 (o1, o2) -> o1.idAsString().compareTo(o2.idAsString());
55
Simon Huntc0f20c12016-05-09 09:30:20 -070056
57 // top level mappings of topology elements by ID
58 private final Map<NodeId, UiClusterMember> cnodeLookup = new HashMap<>();
59 private final Map<RegionId, UiRegion> regionLookup = new HashMap<>();
60 private final Map<DeviceId, UiDevice> deviceLookup = new HashMap<>();
61 private final Map<HostId, UiHost> hostLookup = new HashMap<>();
62 private final Map<UiLinkId, UiLink> linkLookup = new HashMap<>();
63
Simon Huntb1ce2602016-07-23 14:04:31 -070064 // a container for devices, hosts, etc. belonging to no region
65 private final UiRegion nullRegion = new UiRegion(this, null);
66
Simon Hunt23fb1352016-04-11 12:15:19 -070067
Simon Hunt338a3b42016-04-14 09:43:52 -070068 @Override
69 public String toString() {
Simon Huntc0f20c12016-05-09 09:30:20 -070070 return toStringHelper(this)
71 .add("#cnodes", clusterMemberCount())
72 .add("#regions", regionCount())
73 .add("#devices", deviceLookup.size())
74 .add("#hosts", hostLookup.size())
75 .add("#links", linkLookup.size())
76 .toString();
77 }
78
79 @Override
80 public String idAsString() {
81 return DEFAULT_TOPOLOGY_ID;
Simon Hunt338a3b42016-04-14 09:43:52 -070082 }
83
Simon Hunt23fb1352016-04-11 12:15:19 -070084 /**
85 * Clears the topology state; that is, drops all regions, devices, hosts,
86 * links, and cluster members.
87 */
88 public void clear() {
89 log.debug("clearing topology model");
Simon Huntc0f20c12016-05-09 09:30:20 -070090 cnodeLookup.clear();
91 regionLookup.clear();
92 deviceLookup.clear();
93 hostLookup.clear();
94 linkLookup.clear();
Simon Huntb1ce2602016-07-23 14:04:31 -070095
96 nullRegion.destroy();
Simon Hunt23fb1352016-04-11 12:15:19 -070097 }
Simon Hunt338a3b42016-04-14 09:43:52 -070098
Simon Huntd5b96732016-07-08 13:22:27 -070099
100 /**
101 * Returns all the cluster members, sorted by their ID.
102 *
103 * @return all cluster members
104 */
105 public List<UiClusterMember> allClusterMembers() {
106 List<UiClusterMember> members = new ArrayList<>(cnodeLookup.values());
107 Collections.sort(members, CLUSTER_MEMBER_COMPARATOR);
108 return members;
109 }
110
Simon Hunt338a3b42016-04-14 09:43:52 -0700111 /**
112 * Returns the cluster member with the given identifier, or null if no
Simon Huntc0f20c12016-05-09 09:30:20 -0700113 * such member exists.
Simon Hunt338a3b42016-04-14 09:43:52 -0700114 *
115 * @param id cluster node identifier
Simon Huntc0f20c12016-05-09 09:30:20 -0700116 * @return corresponding UI cluster member
Simon Hunt338a3b42016-04-14 09:43:52 -0700117 */
118 public UiClusterMember findClusterMember(NodeId id) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700119 return cnodeLookup.get(id);
Simon Hunt338a3b42016-04-14 09:43:52 -0700120 }
121
122 /**
123 * Adds the given cluster member to the topology model.
124 *
125 * @param member cluster member to add
126 */
127 public void add(UiClusterMember member) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700128 cnodeLookup.put(member.id(), member);
Simon Hunt338a3b42016-04-14 09:43:52 -0700129 }
130
131 /**
Simon Hunt642bc452016-05-04 19:34:45 -0700132 * Removes the given cluster member from the topology model.
133 *
134 * @param member cluster member to remove
135 */
136 public void remove(UiClusterMember member) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700137 UiClusterMember m = cnodeLookup.remove(member.id());
138 if (m != null) {
139 m.destroy();
140 }
Simon Hunt642bc452016-05-04 19:34:45 -0700141 }
142
143 /**
Simon Hunt338a3b42016-04-14 09:43:52 -0700144 * Returns the number of members in the cluster.
145 *
146 * @return number of cluster members
147 */
148 public int clusterMemberCount() {
Simon Huntc0f20c12016-05-09 09:30:20 -0700149 return cnodeLookup.size();
150 }
151
Simon Hunt10973dd2016-08-01 15:50:35 -0700152
153 /**
Simon Hunt4f4ffc32016-08-03 18:30:47 -0700154 * Returns all regions in the model (except the
155 * {@link #nullRegion() null region}).
Simon Hunt10973dd2016-08-01 15:50:35 -0700156 *
157 * @return all regions
158 */
159 public Set<UiRegion> allRegions() {
160 return new HashSet<>(regionLookup.values());
161 }
162
Simon Huntc0f20c12016-05-09 09:30:20 -0700163 /**
Simon Huntb1ce2602016-07-23 14:04:31 -0700164 * Returns a reference to the null-region. That is, the container for
165 * devices, hosts, and links that belong to no region.
166 *
167 * @return the null-region
168 */
169 public UiRegion nullRegion() {
170 return nullRegion;
171 }
172
173 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700174 * Returns the region with the specified identifier, or null if
175 * no such region exists.
176 *
177 * @param id region identifier
178 * @return corresponding UI region
179 */
180 public UiRegion findRegion(RegionId id) {
Simon Hunt4f4ffc32016-08-03 18:30:47 -0700181 return UiRegion.NULL_ID.equals(id) ? nullRegion() : regionLookup.get(id);
Simon Hunt338a3b42016-04-14 09:43:52 -0700182 }
183
184 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700185 * Adds the given region to the topology model.
186 *
187 * @param uiRegion region to add
188 */
189 public void add(UiRegion uiRegion) {
190 regionLookup.put(uiRegion.id(), uiRegion);
Simon Hunt642bc452016-05-04 19:34:45 -0700191 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700192
193 /**
194 * Removes the given region from the topology model.
195 *
196 * @param uiRegion region to remove
197 */
198 public void remove(UiRegion uiRegion) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700199 UiRegion r = regionLookup.remove(uiRegion.id());
200 if (r != null) {
201 r.destroy();
202 }
203 }
204
205 /**
206 * Returns the number of regions configured in the topology.
207 *
208 * @return number of regions
209 */
210 public int regionCount() {
211 return regionLookup.size();
Simon Huntc0f20c12016-05-09 09:30:20 -0700212 }
213
214 /**
Simon Huntb1ce2602016-07-23 14:04:31 -0700215 * Returns all devices in the model.
216 *
217 * @return all devices
218 */
219 public Set<UiDevice> allDevices() {
220 return new HashSet<>(deviceLookup.values());
221 }
222
223 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700224 * Returns the device with the specified identifier, or null if
225 * no such device exists.
226 *
227 * @param id device identifier
228 * @return corresponding UI device
229 */
230 public UiDevice findDevice(DeviceId id) {
231 return deviceLookup.get(id);
232 }
233
234 /**
235 * Adds the given device to the topology model.
236 *
237 * @param uiDevice device to add
238 */
239 public void add(UiDevice uiDevice) {
240 deviceLookup.put(uiDevice.id(), uiDevice);
241 }
242
243 /**
244 * Removes the given device from the topology model.
245 *
246 * @param uiDevice device to remove
247 */
248 public void remove(UiDevice uiDevice) {
249 UiDevice d = deviceLookup.remove(uiDevice.id());
250 if (d != null) {
251 d.destroy();
252 }
253 }
254
255 /**
Simon Hunt58a0dd02016-05-17 11:54:23 -0700256 * Returns the number of devices configured in the topology.
257 *
258 * @return number of devices
259 */
260 public int deviceCount() {
261 return deviceLookup.size();
262 }
263
264 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700265 * Returns all links in the model.
266 *
267 * @return all links
268 */
269 public Set<UiLink> allLinks() {
270 return new HashSet<>(linkLookup.values());
271 }
272
273 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700274 * Returns the link with the specified identifier, or null if no such
275 * link exists.
276 *
277 * @param id the canonicalized link identifier
278 * @return corresponding UI link
279 */
280 public UiLink findLink(UiLinkId id) {
281 return linkLookup.get(id);
282 }
283
284 /**
285 * Adds the given UI link to the topology model.
286 *
287 * @param uiLink link to add
288 */
289 public void add(UiLink uiLink) {
290 linkLookup.put(uiLink.id(), uiLink);
291 }
292
293 /**
294 * Removes the given UI link from the model.
295 *
296 * @param uiLink link to remove
297 */
298 public void remove(UiLink uiLink) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700299 UiLink link = linkLookup.remove(uiLink.id());
Simon Huntc0f20c12016-05-09 09:30:20 -0700300 if (link != null) {
301 link.destroy();
302 }
303 }
304
305 /**
Simon Hunt58a0dd02016-05-17 11:54:23 -0700306 * Returns the number of links configured in the topology.
307 *
308 * @return number of links
309 */
310 public int linkCount() {
311 return linkLookup.size();
312 }
313
314 /**
Simon Hunt4854f3d2016-08-02 18:13:15 -0700315 * Returns all hosts in the model.
316 *
317 * @return all hosts
318 */
319 public Set<UiHost> allHosts() {
320 return new HashSet<>(hostLookup.values());
321 }
322
323 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700324 * Returns the host with the specified identifier, or null if no such
325 * host exists.
326 *
327 * @param id host identifier
328 * @return corresponding UI host
329 */
330 public UiHost findHost(HostId id) {
331 return hostLookup.get(id);
332 }
333
334 /**
335 * Adds the given host to the topology model.
336 *
337 * @param uiHost host to add
338 */
339 public void add(UiHost uiHost) {
340 hostLookup.put(uiHost.id(), uiHost);
341 }
342
343 /**
344 * Removes the given host from the topology model.
345 *
346 * @param uiHost host to remove
347 */
348 public void remove(UiHost uiHost) {
349 UiHost h = hostLookup.remove(uiHost.id());
350 if (h != null) {
351 h.destroy();
352 }
353 }
354
Simon Hunt58a0dd02016-05-17 11:54:23 -0700355 /**
356 * Returns the number of hosts configured in the topology.
357 *
358 * @return number of hosts
359 */
360 public int hostCount() {
361 return hostLookup.size();
362 }
363
364
Simon Huntc0f20c12016-05-09 09:30:20 -0700365 // ==
366 // package private methods for supporting linkage amongst topology entities
367 // ==
368
369 /**
370 * Returns the set of UI devices with the given identifiers.
371 *
372 * @param deviceIds device identifiers
373 * @return set of matching UI device instances
374 */
375 Set<UiDevice> deviceSet(Set<DeviceId> deviceIds) {
376 Set<UiDevice> uiDevices = new HashSet<>();
377 for (DeviceId id : deviceIds) {
378 UiDevice d = deviceLookup.get(id);
379 if (d != null) {
380 uiDevices.add(d);
381 } else {
382 log.warn(E_UNMAPPED, "device", id);
383 }
384 }
385 return uiDevices;
386 }
387
388 /**
389 * Returns the set of UI hosts with the given identifiers.
390 *
391 * @param hostIds host identifiers
392 * @return set of matching UI host instances
393 */
394 Set<UiHost> hostSet(Set<HostId> hostIds) {
395 Set<UiHost> uiHosts = new HashSet<>();
396 for (HostId id : hostIds) {
397 UiHost h = hostLookup.get(id);
398 if (h != null) {
399 uiHosts.add(h);
400 } else {
401 log.warn(E_UNMAPPED, "host", id);
402 }
403 }
404 return uiHosts;
405 }
406
407 /**
408 * Returns the set of UI links with the given identifiers.
409 *
410 * @param uiLinkIds link identifiers
411 * @return set of matching UI link instances
412 */
413 Set<UiLink> linkSet(Set<UiLinkId> uiLinkIds) {
414 Set<UiLink> uiLinks = new HashSet<>();
415 for (UiLinkId id : uiLinkIds) {
416 UiLink link = linkLookup.get(id);
417 if (link != null) {
418 uiLinks.add(link);
419 } else {
420 log.warn(E_UNMAPPED, "link", id);
421 }
422 }
423 return uiLinks;
424 }
425
Simon Hunt58a0dd02016-05-17 11:54:23 -0700426 /**
427 * Returns a detailed (multi-line) string showing the contents of the
428 * topology.
429 *
430 * @return detailed string
431 */
432 public String dumpString() {
433 StringBuilder sb = new StringBuilder("Topology:").append(EOL);
434
435 sb.append(INDENT_1).append("Cluster Members").append(EOL);
436 for (UiClusterMember m : cnodeLookup.values()) {
437 sb.append(INDENT_2).append(m).append(EOL);
438 }
439
440 sb.append(INDENT_1).append("Regions").append(EOL);
441 for (UiRegion r : regionLookup.values()) {
442 sb.append(INDENT_2).append(r).append(EOL);
443 }
444
445 sb.append(INDENT_1).append("Devices").append(EOL);
446 for (UiDevice d : deviceLookup.values()) {
447 sb.append(INDENT_2).append(d).append(EOL);
448 }
449
450 sb.append(INDENT_1).append("Hosts").append(EOL);
451 for (UiHost h : hostLookup.values()) {
452 sb.append(INDENT_2).append(h).append(EOL);
453 }
454
455 sb.append(INDENT_1).append("Links").append(EOL);
456 for (UiLink link : linkLookup.values()) {
457 sb.append(INDENT_2).append(link).append(EOL);
458 }
459 sb.append("------").append(EOL);
460
461 return sb.toString();
462 }
463
Simon Hunt5f6dbf82016-03-30 08:53:33 -0700464}