blob: 4ca6b4246be55eba98f8da21bc96401891a21c11 [file] [log] [blame]
Simon Huntcda9c032016-04-11 10:32:54 -07001/*
2 * Copyright 2016 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
17package org.onosproject.ui.impl.topo.model;
18
Simon Hunt23fb1352016-04-11 12:15:19 -070019import org.onosproject.cluster.ControllerNode;
Simon Hunt642bc452016-05-04 19:34:45 -070020import org.onosproject.cluster.NodeId;
Simon Hunt23fb1352016-04-11 12:15:19 -070021import org.onosproject.cluster.RoleInfo;
Simon Huntcda9c032016-04-11 10:32:54 -070022import org.onosproject.event.EventDispatcher;
23import org.onosproject.net.Device;
Simon Hunt23fb1352016-04-11 12:15:19 -070024import org.onosproject.net.DeviceId;
Simon Huntc0f20c12016-05-09 09:30:20 -070025import org.onosproject.net.EdgeLink;
Simon Hunt23fb1352016-04-11 12:15:19 -070026import org.onosproject.net.Host;
Simon Huntc0f20c12016-05-09 09:30:20 -070027import org.onosproject.net.HostId;
28import org.onosproject.net.HostLocation;
Simon Hunt23fb1352016-04-11 12:15:19 -070029import org.onosproject.net.Link;
30import org.onosproject.net.region.Region;
Simon Huntc0f20c12016-05-09 09:30:20 -070031import org.onosproject.net.region.RegionId;
Simon Hunt642bc452016-05-04 19:34:45 -070032import org.onosproject.ui.model.ServiceBundle;
Simon Hunt338a3b42016-04-14 09:43:52 -070033import org.onosproject.ui.model.topo.UiClusterMember;
Simon Huntcda9c032016-04-11 10:32:54 -070034import org.onosproject.ui.model.topo.UiDevice;
Simon Huntc0f20c12016-05-09 09:30:20 -070035import org.onosproject.ui.model.topo.UiElement;
36import org.onosproject.ui.model.topo.UiHost;
37import org.onosproject.ui.model.topo.UiLink;
38import org.onosproject.ui.model.topo.UiLinkId;
39import org.onosproject.ui.model.topo.UiRegion;
Simon Hunt23fb1352016-04-11 12:15:19 -070040import org.onosproject.ui.model.topo.UiTopology;
Simon Hunt642bc452016-05-04 19:34:45 -070041import org.slf4j.Logger;
42import org.slf4j.LoggerFactory;
Simon Hunt23fb1352016-04-11 12:15:19 -070043
Simon Huntb1ce2602016-07-23 14:04:31 -070044import java.util.HashSet;
Simon Huntd5b96732016-07-08 13:22:27 -070045import java.util.List;
Simon Huntc0f20c12016-05-09 09:30:20 -070046import java.util.Set;
47
48import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
Simon Hunt642bc452016-05-04 19:34:45 -070049import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.CLUSTER_MEMBER_ADDED_OR_UPDATED;
50import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.CLUSTER_MEMBER_REMOVED;
51import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_ADDED_OR_UPDATED;
Simon Hunt23fb1352016-04-11 12:15:19 -070052import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_REMOVED;
Simon Huntc0f20c12016-05-09 09:30:20 -070053import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.HOST_ADDED_OR_UPDATED;
54import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.HOST_MOVED;
55import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.HOST_REMOVED;
56import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.LINK_ADDED_OR_UPDATED;
57import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.LINK_REMOVED;
58import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.REGION_ADDED_OR_UPDATED;
59import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.REGION_REMOVED;
60import static org.onosproject.ui.model.topo.UiLinkId.uiLinkId;
Simon Huntcda9c032016-04-11 10:32:54 -070061
62/**
63 * UI Topology Model cache.
64 */
65class ModelCache {
66
Simon Huntc0f20c12016-05-09 09:30:20 -070067 private static final String E_NO_ELEMENT = "Tried to remove non-member {}: {}";
68
Simon Hunt642bc452016-05-04 19:34:45 -070069 private static final Logger log = LoggerFactory.getLogger(ModelCache.class);
70
71 private final ServiceBundle services;
Simon Huntcda9c032016-04-11 10:32:54 -070072 private final EventDispatcher dispatcher;
Simon Hunt23fb1352016-04-11 12:15:19 -070073 private final UiTopology uiTopology = new UiTopology();
Simon Huntcda9c032016-04-11 10:32:54 -070074
Simon Hunt642bc452016-05-04 19:34:45 -070075 ModelCache(ServiceBundle services, EventDispatcher eventDispatcher) {
76 this.services = services;
Simon Huntcda9c032016-04-11 10:32:54 -070077 this.dispatcher = eventDispatcher;
78 }
79
Simon Hunt338a3b42016-04-14 09:43:52 -070080 @Override
81 public String toString() {
82 return "ModelCache{" + uiTopology + "}";
83 }
84
Simon Huntc0f20c12016-05-09 09:30:20 -070085 private void postEvent(UiModelEvent.Type type, UiElement subject) {
86 dispatcher.post(new UiModelEvent(type, subject));
87 }
88
Simon Huntcda9c032016-04-11 10:32:54 -070089 void clear() {
Simon Hunt23fb1352016-04-11 12:15:19 -070090 uiTopology.clear();
Simon Huntcda9c032016-04-11 10:32:54 -070091 }
92
93 /**
Simon Huntc0f20c12016-05-09 09:30:20 -070094 * Create our internal model of the global topology. An assumption we are
95 * making is that the topology is empty to start.
Simon Huntcda9c032016-04-11 10:32:54 -070096 */
97 void load() {
Simon Huntc0f20c12016-05-09 09:30:20 -070098 loadClusterMembers();
99 loadRegions();
100 loadDevices();
101 loadLinks();
102 loadHosts();
Simon Huntcda9c032016-04-11 10:32:54 -0700103 }
104
105
Simon Huntc0f20c12016-05-09 09:30:20 -0700106 // === CLUSTER MEMBERS
107
108 private UiClusterMember addNewClusterMember(ControllerNode n) {
109 UiClusterMember member = new UiClusterMember(uiTopology, n);
110 uiTopology.add(member);
111 return member;
112 }
113
114 private void updateClusterMember(UiClusterMember member) {
115 ControllerNode.State state = services.cluster().getState(member.id());
116 member.setState(state);
117 member.setMastership(services.mastership().getDevicesOf(member.id()));
118 // NOTE: 'UI-attached' is session-based data, not global, so will
119 // be set elsewhere
120 }
121
122 private void loadClusterMembers() {
123 for (ControllerNode n : services.cluster().getNodes()) {
124 UiClusterMember member = addNewClusterMember(n);
125 updateClusterMember(member);
126 }
127 }
128
129 // invoked from UiSharedTopologyModel cluster event listener
Simon Hunt338a3b42016-04-14 09:43:52 -0700130 void addOrUpdateClusterMember(ControllerNode cnode) {
Simon Hunt642bc452016-05-04 19:34:45 -0700131 NodeId id = cnode.id();
132 UiClusterMember member = uiTopology.findClusterMember(id);
133 if (member == null) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700134 member = addNewClusterMember(cnode);
Simon Hunt338a3b42016-04-14 09:43:52 -0700135 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700136 updateClusterMember(member);
Simon Hunt338a3b42016-04-14 09:43:52 -0700137
Simon Huntc0f20c12016-05-09 09:30:20 -0700138 postEvent(CLUSTER_MEMBER_ADDED_OR_UPDATED, member);
Simon Hunt338a3b42016-04-14 09:43:52 -0700139 }
140
Simon Huntc0f20c12016-05-09 09:30:20 -0700141 // package private for unit test access
142 UiClusterMember accessClusterMember(NodeId id) {
143 return uiTopology.findClusterMember(id);
144 }
145
146 // invoked from UiSharedTopologyModel cluster event listener
Simon Hunt338a3b42016-04-14 09:43:52 -0700147 void removeClusterMember(ControllerNode cnode) {
Simon Hunt642bc452016-05-04 19:34:45 -0700148 NodeId id = cnode.id();
149 UiClusterMember member = uiTopology.findClusterMember(id);
150 if (member != null) {
151 uiTopology.remove(member);
Simon Huntc0f20c12016-05-09 09:30:20 -0700152 postEvent(CLUSTER_MEMBER_REMOVED, member);
Simon Hunt642bc452016-05-04 19:34:45 -0700153 } else {
Simon Huntc0f20c12016-05-09 09:30:20 -0700154 log.warn(E_NO_ELEMENT, "cluster node", id);
Simon Hunt642bc452016-05-04 19:34:45 -0700155 }
Simon Hunt338a3b42016-04-14 09:43:52 -0700156 }
157
Simon Huntd5b96732016-07-08 13:22:27 -0700158 List<UiClusterMember> getAllClusterMembers() {
159 return uiTopology.allClusterMembers();
160 }
161
Simon Huntc0f20c12016-05-09 09:30:20 -0700162
163 // === MASTERSHIP CHANGES
164
165 // invoked from UiSharedTopologyModel mastership listener
Simon Hunt338a3b42016-04-14 09:43:52 -0700166 void updateMasterships(DeviceId deviceId, RoleInfo roleInfo) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700167 // To think about:: do we need to store mastership info?
168 // or can we rely on looking it up live?
Simon Hunt338a3b42016-04-14 09:43:52 -0700169 // TODO: store the updated mastership information
170 // TODO: post event
171 }
172
Simon Huntb1ce2602016-07-23 14:04:31 -0700173 // === THE NULL REGION
174
175 UiRegion nullRegion() {
176 return uiTopology.nullRegion();
177 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700178
179 // === REGIONS
180
181 private UiRegion addNewRegion(Region r) {
182 UiRegion region = new UiRegion(uiTopology, r);
183 uiTopology.add(region);
Simon Huntb1ce2602016-07-23 14:04:31 -0700184 log.debug("Region {} added to topology", region);
Simon Huntc0f20c12016-05-09 09:30:20 -0700185 return region;
186 }
187
188 private void updateRegion(UiRegion region) {
Simon Huntb1ce2602016-07-23 14:04:31 -0700189 RegionId rid = region.id();
190 Set<DeviceId> deviceIds = services.region().getRegionDevices(rid);
191
192 // Make sure device objects refer to their region
193 deviceIds.forEach(d -> {
194 UiDevice dev = uiTopology.findDevice(d);
195 if (dev != null) {
196 dev.setRegionId(rid);
197 } else {
198 // if we don't have the UiDevice in the topology, what can we do?
199 log.warn("Region device {}, but we don't have UiDevice in topology", d);
200 }
201 });
202
203 // Make sure the region object refers to the devices
204 region.reconcileDevices(deviceIds);
Simon Huntc0f20c12016-05-09 09:30:20 -0700205 }
206
207 private void loadRegions() {
208 for (Region r : services.region().getRegions()) {
209 UiRegion region = addNewRegion(r);
210 updateRegion(region);
211 }
212 }
213
214 // invoked from UiSharedTopologyModel region listener
Simon Hunt338a3b42016-04-14 09:43:52 -0700215 void addOrUpdateRegion(Region region) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700216 RegionId id = region.id();
217 UiRegion uiRegion = uiTopology.findRegion(id);
218 if (uiRegion == null) {
219 uiRegion = addNewRegion(region);
220 }
221 updateRegion(uiRegion);
222
223 postEvent(REGION_ADDED_OR_UPDATED, uiRegion);
Simon Hunt338a3b42016-04-14 09:43:52 -0700224 }
225
Simon Hunt58a0dd02016-05-17 11:54:23 -0700226 // package private for unit test access
227 UiRegion accessRegion(RegionId id) {
Simon Huntd5b96732016-07-08 13:22:27 -0700228 return id == null ? null : uiTopology.findRegion(id);
Simon Hunt58a0dd02016-05-17 11:54:23 -0700229 }
230
Simon Huntc0f20c12016-05-09 09:30:20 -0700231 // invoked from UiSharedTopologyModel region listener
Simon Hunt338a3b42016-04-14 09:43:52 -0700232 void removeRegion(Region region) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700233 RegionId id = region.id();
234 UiRegion uiRegion = uiTopology.findRegion(id);
235 if (uiRegion != null) {
236 uiTopology.remove(uiRegion);
237 postEvent(REGION_REMOVED, uiRegion);
238 } else {
239 log.warn(E_NO_ELEMENT, "region", id);
240 }
Simon Hunt338a3b42016-04-14 09:43:52 -0700241 }
242
Simon Hunt10973dd2016-08-01 15:50:35 -0700243 Set<UiRegion> getAllRegions() {
244 return uiTopology.allRegions();
245 }
246
Simon Huntc0f20c12016-05-09 09:30:20 -0700247
248 // === DEVICES
249
250 private UiDevice addNewDevice(Device d) {
251 UiDevice device = new UiDevice(uiTopology, d);
Simon Huntb1ce2602016-07-23 14:04:31 -0700252 updateDevice(device);
Simon Huntc0f20c12016-05-09 09:30:20 -0700253 uiTopology.add(device);
Simon Huntb1ce2602016-07-23 14:04:31 -0700254 log.debug("Device {} added to topology", device);
Simon Huntc0f20c12016-05-09 09:30:20 -0700255 return device;
256 }
257
Simon Huntb1ce2602016-07-23 14:04:31 -0700258 // make sure the UiDevice is tagged with the region it belongs to
Simon Huntc0f20c12016-05-09 09:30:20 -0700259 private void updateDevice(UiDevice device) {
Simon Huntb1ce2602016-07-23 14:04:31 -0700260 Region r = services.region().getRegionForDevice(device.id());
261 RegionId rid = r == null ? UiRegion.NULL_ID : r.id();
262 device.setRegionId(rid);
Simon Huntc0f20c12016-05-09 09:30:20 -0700263 }
264
265 private void loadDevices() {
266 for (Device d : services.device().getDevices()) {
Simon Huntb1ce2602016-07-23 14:04:31 -0700267 addNewDevice(d);
Simon Huntc0f20c12016-05-09 09:30:20 -0700268 }
269 }
270
271 // invoked from UiSharedTopologyModel device listener
Simon Huntcda9c032016-04-11 10:32:54 -0700272 void addOrUpdateDevice(Device device) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700273 DeviceId id = device.id();
274 UiDevice uiDevice = uiTopology.findDevice(id);
275 if (uiDevice == null) {
276 uiDevice = addNewDevice(device);
Simon Huntb1ce2602016-07-23 14:04:31 -0700277 } else {
278 updateDevice(uiDevice);
Simon Huntc0f20c12016-05-09 09:30:20 -0700279 }
Simon Huntcda9c032016-04-11 10:32:54 -0700280
Simon Huntc0f20c12016-05-09 09:30:20 -0700281 postEvent(DEVICE_ADDED_OR_UPDATED, uiDevice);
Simon Huntcda9c032016-04-11 10:32:54 -0700282 }
283
Simon Hunt58a0dd02016-05-17 11:54:23 -0700284 // package private for unit test access
285 UiDevice accessDevice(DeviceId id) {
286 return uiTopology.findDevice(id);
287 }
288
Simon Huntc0f20c12016-05-09 09:30:20 -0700289 // invoked from UiSharedTopologyModel device listener
Simon Huntcda9c032016-04-11 10:32:54 -0700290 void removeDevice(Device device) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700291 DeviceId id = device.id();
292 UiDevice uiDevice = uiTopology.findDevice(id);
293 if (uiDevice != null) {
294 uiTopology.remove(uiDevice);
295 postEvent(DEVICE_REMOVED, uiDevice);
296 } else {
297 log.warn(E_NO_ELEMENT, "device", id);
298 }
Simon Huntcda9c032016-04-11 10:32:54 -0700299 }
300
Simon Hunt4854f3d2016-08-02 18:13:15 -0700301 Set<UiDevice> getAllDevices() {
302 return uiTopology.allDevices();
303 }
304
Simon Huntc0f20c12016-05-09 09:30:20 -0700305
306 // === LINKS
307
308 private UiLink addNewLink(UiLinkId id) {
309 UiLink uiLink = new UiLink(uiTopology, id);
310 uiTopology.add(uiLink);
311 return uiLink;
312 }
313
314 private void updateLink(UiLink uiLink, Link link) {
315 uiLink.attachBackingLink(link);
316 }
317
318 private void loadLinks() {
319 for (Link link : services.link().getLinks()) {
320 UiLinkId id = uiLinkId(link);
321
322 UiLink uiLink = uiTopology.findLink(id);
323 if (uiLink == null) {
324 uiLink = addNewLink(id);
325 }
326 updateLink(uiLink, link);
327 }
328 }
329
330 // invoked from UiSharedTopologyModel link listener
Simon Hunt23fb1352016-04-11 12:15:19 -0700331 void addOrUpdateLink(Link link) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700332 UiLinkId id = uiLinkId(link);
333 UiLink uiLink = uiTopology.findLink(id);
334 if (uiLink == null) {
335 uiLink = addNewLink(id);
336 }
337 updateLink(uiLink, link);
338
339 postEvent(LINK_ADDED_OR_UPDATED, uiLink);
Simon Hunt23fb1352016-04-11 12:15:19 -0700340 }
341
Simon Hunt58a0dd02016-05-17 11:54:23 -0700342 // package private for unit test access
343 UiLink accessLink(UiLinkId id) {
344 return uiTopology.findLink(id);
345 }
346
Simon Huntc0f20c12016-05-09 09:30:20 -0700347 // invoked from UiSharedTopologyModel link listener
Simon Hunt23fb1352016-04-11 12:15:19 -0700348 void removeLink(Link link) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700349 UiLinkId id = uiLinkId(link);
350 UiLink uiLink = uiTopology.findLink(id);
351 if (uiLink != null) {
352 boolean remaining = uiLink.detachBackingLink(link);
353 if (remaining) {
354 postEvent(LINK_ADDED_OR_UPDATED, uiLink);
355 } else {
356 uiTopology.remove(uiLink);
357 postEvent(LINK_REMOVED, uiLink);
358 }
359 } else {
360 log.warn(E_NO_ELEMENT, "link", id);
361 }
Simon Hunt23fb1352016-04-11 12:15:19 -0700362 }
363
Simon Hunt4854f3d2016-08-02 18:13:15 -0700364 Set<UiLink> getAllLinks() {
365 return uiTopology.allLinks();
366 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700367
368 // === HOSTS
369
Simon Hunt58a0dd02016-05-17 11:54:23 -0700370 private EdgeLink synthesizeLink(Host h) {
371 return createEdgeLink(h, true);
372 }
373
Simon Huntc0f20c12016-05-09 09:30:20 -0700374 private UiHost addNewHost(Host h) {
375 UiHost host = new UiHost(uiTopology, h);
376 uiTopology.add(host);
377
Simon Hunt58a0dd02016-05-17 11:54:23 -0700378 EdgeLink elink = synthesizeLink(h);
379 UiLinkId elinkId = uiLinkId(elink);
380 host.setEdgeLinkId(elinkId);
381
382 // add synthesized edge link to the topology
383 UiLink edgeLink = addNewLink(elinkId);
384 edgeLink.attachEdgeLink(elink);
Simon Huntc0f20c12016-05-09 09:30:20 -0700385
386 return host;
387 }
388
Simon Hunt58a0dd02016-05-17 11:54:23 -0700389 private void insertNewUiLink(UiLinkId id, EdgeLink e) {
390 UiLink newEdgeLink = addNewLink(id);
391 newEdgeLink.attachEdgeLink(e);
Simon Huntc0f20c12016-05-09 09:30:20 -0700392
Simon Huntc0f20c12016-05-09 09:30:20 -0700393 }
394
395 private void updateHost(UiHost uiHost, Host h) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700396 UiLink existing = uiTopology.findLink(uiHost.edgeLinkId());
397
398 EdgeLink currentElink = synthesizeLink(h);
399 UiLinkId currentElinkId = uiLinkId(currentElink);
400
401 if (existing != null) {
402 if (!currentElinkId.equals(existing.id())) {
403 // edge link has changed
404 insertNewUiLink(currentElinkId, currentElink);
405 uiHost.setEdgeLinkId(currentElinkId);
406
407 uiTopology.remove(existing);
408 }
409
410 } else {
411 // no previously existing edge link
412 insertNewUiLink(currentElinkId, currentElink);
413 uiHost.setEdgeLinkId(currentElinkId);
414
415 }
416
Simon Huntc0f20c12016-05-09 09:30:20 -0700417 HostLocation hloc = h.location();
418 uiHost.setLocation(hloc.deviceId(), hloc.port());
Simon Huntc0f20c12016-05-09 09:30:20 -0700419 }
420
421 private void loadHosts() {
422 for (Host h : services.host().getHosts()) {
423 UiHost host = addNewHost(h);
424 updateHost(host, h);
425 }
426 }
427
428 // invoked from UiSharedTopologyModel host listener
Simon Hunt23fb1352016-04-11 12:15:19 -0700429 void addOrUpdateHost(Host host) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700430 HostId id = host.id();
431 UiHost uiHost = uiTopology.findHost(id);
432 if (uiHost == null) {
433 uiHost = addNewHost(host);
434 }
435 updateHost(uiHost, host);
436
437 postEvent(HOST_ADDED_OR_UPDATED, uiHost);
Simon Hunt23fb1352016-04-11 12:15:19 -0700438 }
439
Simon Huntc0f20c12016-05-09 09:30:20 -0700440 // invoked from UiSharedTopologyModel host listener
Simon Hunt23fb1352016-04-11 12:15:19 -0700441 void moveHost(Host host, Host prevHost) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700442 UiHost uiHost = uiTopology.findHost(prevHost.id());
Simon Hunt58a0dd02016-05-17 11:54:23 -0700443 if (uiHost != null) {
444 updateHost(uiHost, host);
445 postEvent(HOST_MOVED, uiHost);
446 } else {
447 log.warn(E_NO_ELEMENT, "host", prevHost.id());
448 }
449 }
Simon Huntc0f20c12016-05-09 09:30:20 -0700450
Simon Hunt58a0dd02016-05-17 11:54:23 -0700451 // package private for unit test access
452 UiHost accessHost(HostId id) {
453 return uiTopology.findHost(id);
Simon Hunt23fb1352016-04-11 12:15:19 -0700454 }
455
Simon Huntc0f20c12016-05-09 09:30:20 -0700456 // invoked from UiSharedTopologyModel host listener
Simon Hunt23fb1352016-04-11 12:15:19 -0700457 void removeHost(Host host) {
Simon Huntc0f20c12016-05-09 09:30:20 -0700458 HostId id = host.id();
459 UiHost uiHost = uiTopology.findHost(id);
460 if (uiHost != null) {
Simon Hunt58a0dd02016-05-17 11:54:23 -0700461 UiLink edgeLink = uiTopology.findLink(uiHost.edgeLinkId());
462 uiTopology.remove(edgeLink);
Simon Huntc0f20c12016-05-09 09:30:20 -0700463 uiTopology.remove(uiHost);
Simon Huntc0f20c12016-05-09 09:30:20 -0700464 postEvent(HOST_REMOVED, uiHost);
465 } else {
466 log.warn(E_NO_ELEMENT, "host", id);
467 }
Simon Hunt23fb1352016-04-11 12:15:19 -0700468 }
Simon Hunt338a3b42016-04-14 09:43:52 -0700469
Simon Hunt4854f3d2016-08-02 18:13:15 -0700470 Set<UiHost> getAllHosts() {
471 return uiTopology.allHosts();
472 }
473
Simon Huntc0f20c12016-05-09 09:30:20 -0700474
Simon Huntb1ce2602016-07-23 14:04:31 -0700475 /**
476 * Refreshes the internal state.
477 */
478 public void refresh() {
479 // fix up internal linkages if they aren't correct
480
481 // at the moment, this is making sure devices are in the correct region
482 Set<UiDevice> allDevices = uiTopology.allDevices();
483
484 services.region().getRegions().forEach(r -> {
485 RegionId rid = r.id();
486 UiRegion region = uiTopology.findRegion(rid);
487 if (region != null) {
488 Set<DeviceId> deviceIds = services.region().getRegionDevices(rid);
489 region.reconcileDevices(deviceIds);
490
491 deviceIds.forEach(devId -> {
492 UiDevice dev = uiTopology.findDevice(devId);
493 if (dev != null) {
494 dev.setRegionId(r.id());
495 allDevices.remove(dev);
496 } else {
497 log.warn("Region device ID {} but no UiDevice in topology",
498 devId);
499 }
500 });
501 } else {
502 log.warn("No UiRegion in topology for ID {}", rid);
503 }
504 });
505
506 // what is left over, must belong to the null-region
507 Set<DeviceId> leftOver = new HashSet<>(allDevices.size());
508 allDevices.forEach(d -> leftOver.add(d.id()));
509 uiTopology.nullRegion().reconcileDevices(leftOver);
510 }
511
Simon Huntc0f20c12016-05-09 09:30:20 -0700512 // === CACHE STATISTICS
513
Simon Hunt338a3b42016-04-14 09:43:52 -0700514 /**
Simon Hunt58a0dd02016-05-17 11:54:23 -0700515 * Returns a detailed (multi-line) string showing the contents of the cache.
516 *
517 * @return detailed string
518 */
519 public String dumpString() {
520 return uiTopology.dumpString();
521 }
522
523 /**
Simon Hunt338a3b42016-04-14 09:43:52 -0700524 * Returns the number of members in the cluster.
525 *
526 * @return number of cluster members
527 */
528 public int clusterMemberCount() {
529 return uiTopology.clusterMemberCount();
530 }
531
532 /**
Simon Huntc0f20c12016-05-09 09:30:20 -0700533 * Returns the number of regions in the topology.
Simon Hunt338a3b42016-04-14 09:43:52 -0700534 *
535 * @return number of regions
536 */
537 public int regionCount() {
538 return uiTopology.regionCount();
539 }
Simon Hunt58a0dd02016-05-17 11:54:23 -0700540
541 /**
542 * Returns the number of devices in the topology.
543 *
544 * @return number of devices
545 */
546 public int deviceCount() {
547 return uiTopology.deviceCount();
548 }
549
550 /**
551 * Returns the number of links in the topology.
552 *
553 * @return number of links
554 */
555 public int linkCount() {
556 return uiTopology.linkCount();
557 }
558
559 /**
560 * Returns the number of hosts in the topology.
561 *
562 * @return number of hosts
563 */
564 public int hostCount() {
565 return uiTopology.hostCount();
566 }
Simon Huntd5b96732016-07-08 13:22:27 -0700567
Simon Huntcda9c032016-04-11 10:32:54 -0700568}