blob: dd601eb3b500480b2e2d4e0aaddadd89b6ecc068 [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
152 /**
Simon Huntb1ce2602016-07-23 14:04:31 -0700153 * Returns a reference to the null-region. That is, the container for
154 * devices, hosts, and links that belong to no region.
155 *
156 * @return the null-region
157 */
158 public UiRegion nullRegion() {
159 return nullRegion;
160 }
161
162 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700163 * Returns the region with the specified identifier, or null if
164 * no such region exists.
165 *
166 * @param id region identifier
167 * @return corresponding UI region
168 */
169 public UiRegion findRegion(RegionId id) {
170 return regionLookup.get(id);
Simon Hunt338a3b42016-04-14 09:43:52 -0700171 }
172
173 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700174 * Adds the given region to the topology model.
175 *
176 * @param uiRegion region to add
177 */
178 public void add(UiRegion uiRegion) {
179 regionLookup.put(uiRegion.id(), uiRegion);
Simon Hunt642bc452016-05-04 19:34:45 -0700180 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700181
182 /**
183 * Removes the given region from the topology model.
184 *
185 * @param uiRegion region to remove
186 */
187 public void remove(UiRegion uiRegion) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700188 UiRegion r = regionLookup.remove(uiRegion.id());
189 if (r != null) {
190 r.destroy();
191 }
192 }
193
194 /**
195 * Returns the number of regions configured in the topology.
196 *
197 * @return number of regions
198 */
199 public int regionCount() {
200 return regionLookup.size();
Simon Huntc0f20c12016-05-09 09:30:20 -0700201 }
202
203 /**
Simon Huntb1ce2602016-07-23 14:04:31 -0700204 * Returns all devices in the model.
205 *
206 * @return all devices
207 */
208 public Set<UiDevice> allDevices() {
209 return new HashSet<>(deviceLookup.values());
210 }
211
212 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700213 * Returns the device with the specified identifier, or null if
214 * no such device exists.
215 *
216 * @param id device identifier
217 * @return corresponding UI device
218 */
219 public UiDevice findDevice(DeviceId id) {
220 return deviceLookup.get(id);
221 }
222
223 /**
224 * Adds the given device to the topology model.
225 *
226 * @param uiDevice device to add
227 */
228 public void add(UiDevice uiDevice) {
229 deviceLookup.put(uiDevice.id(), uiDevice);
230 }
231
232 /**
233 * Removes the given device from the topology model.
234 *
235 * @param uiDevice device to remove
236 */
237 public void remove(UiDevice uiDevice) {
238 UiDevice d = deviceLookup.remove(uiDevice.id());
239 if (d != null) {
240 d.destroy();
241 }
242 }
243
244 /**
Simon Hunt58a0dd02016-05-17 11:54:23 -0700245 * Returns the number of devices configured in the topology.
246 *
247 * @return number of devices
248 */
249 public int deviceCount() {
250 return deviceLookup.size();
251 }
252
253 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700254 * Returns the link with the specified identifier, or null if no such
255 * link exists.
256 *
257 * @param id the canonicalized link identifier
258 * @return corresponding UI link
259 */
260 public UiLink findLink(UiLinkId id) {
261 return linkLookup.get(id);
262 }
263
264 /**
265 * Adds the given UI link to the topology model.
266 *
267 * @param uiLink link to add
268 */
269 public void add(UiLink uiLink) {
270 linkLookup.put(uiLink.id(), uiLink);
271 }
272
273 /**
274 * Removes the given UI link from the model.
275 *
276 * @param uiLink link to remove
277 */
278 public void remove(UiLink uiLink) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700279 UiLink link = linkLookup.remove(uiLink.id());
Simon Huntc0f20c12016-05-09 09:30:20 -0700280 if (link != null) {
281 link.destroy();
282 }
283 }
284
285 /**
Simon Hunt58a0dd02016-05-17 11:54:23 -0700286 * Returns the number of links configured in the topology.
287 *
288 * @return number of links
289 */
290 public int linkCount() {
291 return linkLookup.size();
292 }
293
294 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700295 * Returns the host with the specified identifier, or null if no such
296 * host exists.
297 *
298 * @param id host identifier
299 * @return corresponding UI host
300 */
301 public UiHost findHost(HostId id) {
302 return hostLookup.get(id);
303 }
304
305 /**
306 * Adds the given host to the topology model.
307 *
308 * @param uiHost host to add
309 */
310 public void add(UiHost uiHost) {
311 hostLookup.put(uiHost.id(), uiHost);
312 }
313
314 /**
315 * Removes the given host from the topology model.
316 *
317 * @param uiHost host to remove
318 */
319 public void remove(UiHost uiHost) {
320 UiHost h = hostLookup.remove(uiHost.id());
321 if (h != null) {
322 h.destroy();
323 }
324 }
325
Simon Hunt58a0dd02016-05-17 11:54:23 -0700326 /**
327 * Returns the number of hosts configured in the topology.
328 *
329 * @return number of hosts
330 */
331 public int hostCount() {
332 return hostLookup.size();
333 }
334
335
Simon Huntc0f20c12016-05-09 09:30:20 -0700336 // ==
337 // package private methods for supporting linkage amongst topology entities
338 // ==
339
340 /**
341 * Returns the set of UI devices with the given identifiers.
342 *
343 * @param deviceIds device identifiers
344 * @return set of matching UI device instances
345 */
346 Set<UiDevice> deviceSet(Set<DeviceId> deviceIds) {
347 Set<UiDevice> uiDevices = new HashSet<>();
348 for (DeviceId id : deviceIds) {
349 UiDevice d = deviceLookup.get(id);
350 if (d != null) {
351 uiDevices.add(d);
352 } else {
353 log.warn(E_UNMAPPED, "device", id);
354 }
355 }
356 return uiDevices;
357 }
358
359 /**
360 * Returns the set of UI hosts with the given identifiers.
361 *
362 * @param hostIds host identifiers
363 * @return set of matching UI host instances
364 */
365 Set<UiHost> hostSet(Set<HostId> hostIds) {
366 Set<UiHost> uiHosts = new HashSet<>();
367 for (HostId id : hostIds) {
368 UiHost h = hostLookup.get(id);
369 if (h != null) {
370 uiHosts.add(h);
371 } else {
372 log.warn(E_UNMAPPED, "host", id);
373 }
374 }
375 return uiHosts;
376 }
377
378 /**
379 * Returns the set of UI links with the given identifiers.
380 *
381 * @param uiLinkIds link identifiers
382 * @return set of matching UI link instances
383 */
384 Set<UiLink> linkSet(Set<UiLinkId> uiLinkIds) {
385 Set<UiLink> uiLinks = new HashSet<>();
386 for (UiLinkId id : uiLinkIds) {
387 UiLink link = linkLookup.get(id);
388 if (link != null) {
389 uiLinks.add(link);
390 } else {
391 log.warn(E_UNMAPPED, "link", id);
392 }
393 }
394 return uiLinks;
395 }
396
Simon Hunt58a0dd02016-05-17 11:54:23 -0700397 /**
398 * Returns a detailed (multi-line) string showing the contents of the
399 * topology.
400 *
401 * @return detailed string
402 */
403 public String dumpString() {
404 StringBuilder sb = new StringBuilder("Topology:").append(EOL);
405
406 sb.append(INDENT_1).append("Cluster Members").append(EOL);
407 for (UiClusterMember m : cnodeLookup.values()) {
408 sb.append(INDENT_2).append(m).append(EOL);
409 }
410
411 sb.append(INDENT_1).append("Regions").append(EOL);
412 for (UiRegion r : regionLookup.values()) {
413 sb.append(INDENT_2).append(r).append(EOL);
414 }
415
416 sb.append(INDENT_1).append("Devices").append(EOL);
417 for (UiDevice d : deviceLookup.values()) {
418 sb.append(INDENT_2).append(d).append(EOL);
419 }
420
421 sb.append(INDENT_1).append("Hosts").append(EOL);
422 for (UiHost h : hostLookup.values()) {
423 sb.append(INDENT_2).append(h).append(EOL);
424 }
425
426 sb.append(INDENT_1).append("Links").append(EOL);
427 for (UiLink link : linkLookup.values()) {
428 sb.append(INDENT_2).append(link).append(EOL);
429 }
430 sb.append("------").append(EOL);
431
432 return sb.toString();
433 }
434
Simon Hunt5f6dbf82016-03-30 08:53:33 -0700435}