Committed by
Gerrit Code Review
Implementing region hosts for topology 2
Change-Id: I6d1e45b1152b2387d4ff981dc0666868235eb1c3
Showing
10 changed files
with
188 additions
and
26 deletions
... | @@ -18,6 +18,7 @@ package org.onosproject.net.region; | ... | @@ -18,6 +18,7 @@ package org.onosproject.net.region; |
18 | 18 | ||
19 | import org.onosproject.event.ListenerService; | 19 | import org.onosproject.event.ListenerService; |
20 | import org.onosproject.net.DeviceId; | 20 | import org.onosproject.net.DeviceId; |
21 | +import org.onosproject.net.HostId; | ||
21 | 22 | ||
22 | import java.util.Set; | 23 | import java.util.Set; |
23 | 24 | ||
... | @@ -59,4 +60,12 @@ public interface RegionService extends ListenerService<RegionEvent, RegionListen | ... | @@ -59,4 +60,12 @@ public interface RegionService extends ListenerService<RegionEvent, RegionListen |
59 | */ | 60 | */ |
60 | Set<DeviceId> getRegionDevices(RegionId regionId); | 61 | Set<DeviceId> getRegionDevices(RegionId regionId); |
61 | 62 | ||
63 | + /** | ||
64 | + * Returns the set of hosts that belong to the specified region. | ||
65 | + * | ||
66 | + * @param regionId region identifier | ||
67 | + * @return set of identifiers for hosts in the given region | ||
68 | + */ | ||
69 | + Set<HostId> getRegionHosts(RegionId regionId); | ||
70 | + | ||
62 | } | 71 | } | ... | ... |
... | @@ -17,6 +17,7 @@ package org.onosproject.net.region; | ... | @@ -17,6 +17,7 @@ package org.onosproject.net.region; |
17 | 17 | ||
18 | import org.onosproject.cluster.NodeId; | 18 | import org.onosproject.cluster.NodeId; |
19 | import org.onosproject.net.DeviceId; | 19 | import org.onosproject.net.DeviceId; |
20 | +import org.onosproject.net.HostId; | ||
20 | import org.onosproject.store.Store; | 21 | import org.onosproject.store.Store; |
21 | 22 | ||
22 | import java.util.Collection; | 23 | import java.util.Collection; |
... | @@ -110,4 +111,12 @@ public interface RegionStore extends Store<RegionEvent, RegionStoreDelegate> { | ... | @@ -110,4 +111,12 @@ public interface RegionStore extends Store<RegionEvent, RegionStoreDelegate> { |
110 | */ | 111 | */ |
111 | void removeDevices(RegionId regionId, Collection<DeviceId> deviceIds); | 112 | void removeDevices(RegionId regionId, Collection<DeviceId> deviceIds); |
112 | 113 | ||
114 | + /** | ||
115 | + * Returns the set of hosts that belong to the specified region. | ||
116 | + * | ||
117 | + * @param regionId region identifier | ||
118 | + * @return set of identifiers for hosts in the given region | ||
119 | + */ | ||
120 | + Set<HostId> getRegionHosts(RegionId regionId); | ||
121 | + | ||
113 | } | 122 | } | ... | ... |
... | @@ -20,6 +20,7 @@ import org.onosproject.net.DeviceId; | ... | @@ -20,6 +20,7 @@ import org.onosproject.net.DeviceId; |
20 | import org.onosproject.net.Host; | 20 | import org.onosproject.net.Host; |
21 | import org.onosproject.net.HostId; | 21 | import org.onosproject.net.HostId; |
22 | import org.onosproject.net.PortNumber; | 22 | import org.onosproject.net.PortNumber; |
23 | +import org.onosproject.net.region.RegionId; | ||
23 | 24 | ||
24 | import static com.google.common.base.MoreObjects.toStringHelper; | 25 | import static com.google.common.base.MoreObjects.toStringHelper; |
25 | 26 | ||
... | @@ -36,6 +37,7 @@ public class UiHost extends UiNode { | ... | @@ -36,6 +37,7 @@ public class UiHost extends UiNode { |
36 | private PortNumber locPort; | 37 | private PortNumber locPort; |
37 | 38 | ||
38 | private UiLinkId edgeLinkId; | 39 | private UiLinkId edgeLinkId; |
40 | + private RegionId regionId; | ||
39 | 41 | ||
40 | /** | 42 | /** |
41 | * Creates a new UI host. | 43 | * Creates a new UI host. |
... | @@ -70,6 +72,15 @@ public class UiHost extends UiNode { | ... | @@ -70,6 +72,15 @@ public class UiHost extends UiNode { |
70 | return host.id(); | 72 | return host.id(); |
71 | } | 73 | } |
72 | 74 | ||
75 | + /** | ||
76 | + * Sets the ID of the region to which this device belongs. | ||
77 | + * | ||
78 | + * @param regionId region identifier | ||
79 | + */ | ||
80 | + public void setRegionId(RegionId regionId) { | ||
81 | + this.regionId = regionId; | ||
82 | + } | ||
83 | + | ||
73 | @Override | 84 | @Override |
74 | public String idAsString() { | 85 | public String idAsString() { |
75 | return id().toString(); | 86 | return id().toString(); | ... | ... |
... | @@ -241,6 +241,17 @@ public class UiRegion extends UiNode { | ... | @@ -241,6 +241,17 @@ public class UiRegion extends UiNode { |
241 | return topology.deviceSet(deviceIds); | 241 | return topology.deviceSet(deviceIds); |
242 | } | 242 | } |
243 | 243 | ||
244 | + | ||
245 | + /** | ||
246 | + * Make sure we have only these hosts in the region. | ||
247 | + * | ||
248 | + * @param hosts hosts in the region | ||
249 | + */ | ||
250 | + public void reconcileHosts(Set<HostId> hosts) { | ||
251 | + hostIds.clear(); | ||
252 | + hostIds.addAll(hosts); | ||
253 | + } | ||
254 | + | ||
244 | /** | 255 | /** |
245 | * Returns the set of host identifiers for this region. | 256 | * Returns the set of host identifiers for this region. |
246 | * | 257 | * |
... | @@ -260,6 +271,15 @@ public class UiRegion extends UiNode { | ... | @@ -260,6 +271,15 @@ public class UiRegion extends UiNode { |
260 | } | 271 | } |
261 | 272 | ||
262 | /** | 273 | /** |
274 | + * Returns the count of devices in this region. | ||
275 | + * | ||
276 | + * @return the device count | ||
277 | + */ | ||
278 | + public int hostCount() { | ||
279 | + return hostIds.size(); | ||
280 | + } | ||
281 | + | ||
282 | + /** | ||
263 | * Returns the order in which layers should be rendered. Lower layers | 283 | * Returns the order in which layers should be rendered. Lower layers |
264 | * come earlier in the list. For example, to indicate that nodes in the | 284 | * come earlier in the list. For example, to indicate that nodes in the |
265 | * optical layer should be rendered "below" nodes in the packet layer, | 285 | * optical layer should be rendered "below" nodes in the packet layer, | ... | ... |
... | @@ -25,6 +25,7 @@ import org.apache.felix.scr.annotations.Service; | ... | @@ -25,6 +25,7 @@ import org.apache.felix.scr.annotations.Service; |
25 | import org.onosproject.cluster.NodeId; | 25 | import org.onosproject.cluster.NodeId; |
26 | import org.onosproject.event.AbstractListenerManager; | 26 | import org.onosproject.event.AbstractListenerManager; |
27 | import org.onosproject.net.DeviceId; | 27 | import org.onosproject.net.DeviceId; |
28 | +import org.onosproject.net.HostId; | ||
28 | import org.onosproject.net.region.Region; | 29 | import org.onosproject.net.region.Region; |
29 | import org.onosproject.net.region.RegionAdminService; | 30 | import org.onosproject.net.region.RegionAdminService; |
30 | import org.onosproject.net.region.RegionEvent; | 31 | import org.onosproject.net.region.RegionEvent; |
... | @@ -149,4 +150,11 @@ public class RegionManager extends AbstractListenerManager<RegionEvent, RegionLi | ... | @@ -149,4 +150,11 @@ public class RegionManager extends AbstractListenerManager<RegionEvent, RegionLi |
149 | return store.getRegionDevices(regionId); | 150 | return store.getRegionDevices(regionId); |
150 | } | 151 | } |
151 | 152 | ||
153 | + @Override | ||
154 | + public Set<HostId> getRegionHosts(RegionId regionId) { | ||
155 | + checkPermission(REGION_READ); | ||
156 | + checkNotNull(regionId, REGION_ID_NULL); | ||
157 | + return store.getRegionHosts(regionId); | ||
158 | + } | ||
159 | + | ||
152 | } | 160 | } | ... | ... |
... | @@ -27,6 +27,7 @@ import org.apache.felix.scr.annotations.Service; | ... | @@ -27,6 +27,7 @@ import org.apache.felix.scr.annotations.Service; |
27 | import org.onlab.util.Identifier; | 27 | import org.onlab.util.Identifier; |
28 | import org.onosproject.cluster.NodeId; | 28 | import org.onosproject.cluster.NodeId; |
29 | import org.onosproject.net.DeviceId; | 29 | import org.onosproject.net.DeviceId; |
30 | +import org.onosproject.net.HostId; | ||
30 | import org.onosproject.net.region.DefaultRegion; | 31 | import org.onosproject.net.region.DefaultRegion; |
31 | import org.onosproject.net.region.Region; | 32 | import org.onosproject.net.region.Region; |
32 | import org.onosproject.net.region.RegionEvent; | 33 | import org.onosproject.net.region.RegionEvent; |
... | @@ -78,6 +79,7 @@ public class DistributedRegionStore | ... | @@ -78,6 +79,7 @@ public class DistributedRegionStore |
78 | 79 | ||
79 | private ConsistentMap<RegionId, Set<DeviceId>> membershipRepo; | 80 | private ConsistentMap<RegionId, Set<DeviceId>> membershipRepo; |
80 | private Map<RegionId, Set<DeviceId>> regionDevices; | 81 | private Map<RegionId, Set<DeviceId>> regionDevices; |
82 | + private Map<RegionId, Set<HostId>> regionHosts; | ||
81 | 83 | ||
82 | private Map<DeviceId, Region> regionsByDevice = new HashMap<>(); | 84 | private Map<DeviceId, Region> regionsByDevice = new HashMap<>(); |
83 | 85 | ||
... | @@ -140,6 +142,12 @@ public class DistributedRegionStore | ... | @@ -140,6 +142,12 @@ public class DistributedRegionStore |
140 | } | 142 | } |
141 | 143 | ||
142 | @Override | 144 | @Override |
145 | + public Set<HostId> getRegionHosts(RegionId regionId) { | ||
146 | + Set<HostId> hostIds = regionHosts.get(regionId); | ||
147 | + return hostIds != null ? ImmutableSet.copyOf(hostIds) : ImmutableSet.of(); | ||
148 | + } | ||
149 | + | ||
150 | + @Override | ||
143 | public Region createRegion(RegionId regionId, String name, Region.Type type, | 151 | public Region createRegion(RegionId regionId, String name, Region.Type type, |
144 | List<Set<NodeId>> masterNodeIds) { | 152 | List<Set<NodeId>> masterNodeIds) { |
145 | return regionsRepo.compute(regionId, (id, region) -> { | 153 | return regionsRepo.compute(regionId, (id, region) -> { | ... | ... |
... | @@ -387,7 +387,8 @@ class Topo2Jsonifier { | ... | @@ -387,7 +387,8 @@ class Topo2Jsonifier { |
387 | .put("id", region.idAsString()) | 387 | .put("id", region.idAsString()) |
388 | .put("name", region.name()) | 388 | .put("name", region.name()) |
389 | .put("nodeType", REGION) | 389 | .put("nodeType", REGION) |
390 | - .put("nDevs", region.deviceCount()); | 390 | + .put("nDevs", region.deviceCount()) |
391 | + .put("nHosts", region.hostCount()); | ||
391 | // TODO: complete closed-region details | 392 | // TODO: complete closed-region details |
392 | 393 | ||
393 | addMetaUi(node, region.idAsString()); | 394 | addMetaUi(node, region.idAsString()); | ... | ... |
... | @@ -193,6 +193,7 @@ class ModelCache { | ... | @@ -193,6 +193,7 @@ class ModelCache { |
193 | private void updateRegion(UiRegion region) { | 193 | private void updateRegion(UiRegion region) { |
194 | RegionId rid = region.id(); | 194 | RegionId rid = region.id(); |
195 | Set<DeviceId> deviceIds = services.region().getRegionDevices(rid); | 195 | Set<DeviceId> deviceIds = services.region().getRegionDevices(rid); |
196 | + Set<HostId> hostIds = services.region().getRegionHosts(rid); | ||
196 | 197 | ||
197 | // Make sure device objects refer to their region | 198 | // Make sure device objects refer to their region |
198 | deviceIds.forEach(d -> { | 199 | deviceIds.forEach(d -> { |
... | @@ -205,8 +206,19 @@ class ModelCache { | ... | @@ -205,8 +206,19 @@ class ModelCache { |
205 | } | 206 | } |
206 | }); | 207 | }); |
207 | 208 | ||
209 | + hostIds.forEach(d -> { | ||
210 | + UiHost host = uiTopology.findHost(d); | ||
211 | + if (host != null) { | ||
212 | + host.setRegionId(rid); | ||
213 | + } else { | ||
214 | + // if we don't have the UiDevice in the topology, what can we do? | ||
215 | + log.warn("Region host {}, but we don't have UiHost in topology", d); | ||
216 | + } | ||
217 | + }); | ||
218 | + | ||
208 | // Make sure the region object refers to the devices | 219 | // Make sure the region object refers to the devices |
209 | region.reconcileDevices(deviceIds); | 220 | region.reconcileDevices(deviceIds); |
221 | + region.reconcileHosts(hostIds); | ||
210 | 222 | ||
211 | fixupContainmentHierarchy(region); | 223 | fixupContainmentHierarchy(region); |
212 | } | 224 | } |
... | @@ -526,26 +538,17 @@ class ModelCache { | ... | @@ -526,26 +538,17 @@ class ModelCache { |
526 | fixupContainmentHierarchy(uiTopology.nullRegion()); | 538 | fixupContainmentHierarchy(uiTopology.nullRegion()); |
527 | uiTopology.allRegions().forEach(this::fixupContainmentHierarchy); | 539 | uiTopology.allRegions().forEach(this::fixupContainmentHierarchy); |
528 | 540 | ||
529 | - // make sure devices are in the correct region | 541 | + // make sure devices and hosts are in the correct region |
530 | Set<UiDevice> allDevices = uiTopology.allDevices(); | 542 | Set<UiDevice> allDevices = uiTopology.allDevices(); |
543 | + Set<UiHost> allHosts = uiTopology.allHosts(); | ||
531 | 544 | ||
532 | services.region().getRegions().forEach(r -> { | 545 | services.region().getRegions().forEach(r -> { |
533 | RegionId rid = r.id(); | 546 | RegionId rid = r.id(); |
534 | UiRegion region = uiTopology.findRegion(rid); | 547 | UiRegion region = uiTopology.findRegion(rid); |
535 | if (region != null) { | 548 | if (region != null) { |
536 | - Set<DeviceId> deviceIds = services.region().getRegionDevices(rid); | 549 | + reconcileDevicesWithRegion(allDevices, r, rid, region); |
537 | - region.reconcileDevices(deviceIds); | 550 | + reconcileHostsWithRegion(allHosts, r, rid, region); |
538 | - | 551 | + |
539 | - deviceIds.forEach(devId -> { | ||
540 | - UiDevice dev = uiTopology.findDevice(devId); | ||
541 | - if (dev != null) { | ||
542 | - dev.setRegionId(r.id()); | ||
543 | - allDevices.remove(dev); | ||
544 | - } else { | ||
545 | - log.warn("Region device ID {} but no UiDevice in topology", | ||
546 | - devId); | ||
547 | - } | ||
548 | - }); | ||
549 | } else { | 552 | } else { |
550 | log.warn("No UiRegion in topology for ID {}", rid); | 553 | log.warn("No UiRegion in topology for ID {}", rid); |
551 | } | 554 | } |
... | @@ -556,11 +559,49 @@ class ModelCache { | ... | @@ -556,11 +559,49 @@ class ModelCache { |
556 | allDevices.forEach(d -> leftOver.add(d.id())); | 559 | allDevices.forEach(d -> leftOver.add(d.id())); |
557 | uiTopology.nullRegion().reconcileDevices(leftOver); | 560 | uiTopology.nullRegion().reconcileDevices(leftOver); |
558 | 561 | ||
562 | + Set<HostId> leftOverHosts = new HashSet<>(allHosts.size()); | ||
563 | + allHosts.forEach(h -> leftOverHosts.add(h.id())); | ||
564 | + uiTopology.nullRegion().reconcileHosts(leftOverHosts); | ||
565 | + | ||
559 | // now that we have correct region hierarchy, and devices are in their | 566 | // now that we have correct region hierarchy, and devices are in their |
560 | // respective regions, we can compute synthetic links for each region. | 567 | // respective regions, we can compute synthetic links for each region. |
561 | uiTopology.computeSynthLinks(); | 568 | uiTopology.computeSynthLinks(); |
562 | } | 569 | } |
563 | 570 | ||
571 | + private void reconcileHostsWithRegion(Set<UiHost> allHosts, Region r, | ||
572 | + RegionId rid, UiRegion region) { | ||
573 | + Set<HostId> hostIds = services.region().getRegionHosts(rid); | ||
574 | + region.reconcileHosts(hostIds); | ||
575 | + | ||
576 | + hostIds.forEach(hId -> { | ||
577 | + UiHost h = uiTopology.findHost(hId); | ||
578 | + if (h != null) { | ||
579 | + h.setRegionId(r.id()); | ||
580 | + allHosts.remove(h); | ||
581 | + } else { | ||
582 | + log.warn("Region host ID {} but no UiHost in topology", | ||
583 | + hId); | ||
584 | + } | ||
585 | + }); | ||
586 | + } | ||
587 | + | ||
588 | + private void reconcileDevicesWithRegion(Set<UiDevice> allDevices, Region r, | ||
589 | + RegionId rid, UiRegion region) { | ||
590 | + Set<DeviceId> deviceIds = services.region().getRegionDevices(rid); | ||
591 | + region.reconcileDevices(deviceIds); | ||
592 | + | ||
593 | + deviceIds.forEach(devId -> { | ||
594 | + UiDevice dev = uiTopology.findDevice(devId); | ||
595 | + if (dev != null) { | ||
596 | + dev.setRegionId(r.id()); | ||
597 | + allDevices.remove(dev); | ||
598 | + } else { | ||
599 | + log.warn("Region device ID {} but no UiDevice in topology", | ||
600 | + devId); | ||
601 | + } | ||
602 | + }); | ||
603 | + } | ||
604 | + | ||
564 | 605 | ||
565 | // === CACHE STATISTICS | 606 | // === CACHE STATISTICS |
566 | 607 | ... | ... |
... | @@ -52,7 +52,6 @@ import org.onosproject.net.provider.ProviderId; | ... | @@ -52,7 +52,6 @@ import org.onosproject.net.provider.ProviderId; |
52 | import org.onosproject.net.region.DefaultRegion; | 52 | import org.onosproject.net.region.DefaultRegion; |
53 | import org.onosproject.net.region.Region; | 53 | import org.onosproject.net.region.Region; |
54 | import org.onosproject.net.region.RegionId; | 54 | import org.onosproject.net.region.RegionId; |
55 | -import org.onosproject.net.region.RegionListener; | ||
56 | import org.onosproject.net.region.RegionService; | 55 | import org.onosproject.net.region.RegionService; |
57 | import org.onosproject.ui.UiTopoLayoutService; | 56 | import org.onosproject.ui.UiTopoLayoutService; |
58 | import org.onosproject.ui.impl.AbstractUiImplTest; | 57 | import org.onosproject.ui.impl.AbstractUiImplTest; |
... | @@ -501,8 +500,7 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -501,8 +500,7 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
501 | } | 500 | } |
502 | } | 501 | } |
503 | 502 | ||
504 | - // TODO: consider implementing RegionServiceAdapter and extending that here | 503 | + private static class MockRegionService extends RegionServiceAdapter { |
505 | - private static class MockRegionService implements RegionService { | ||
506 | 504 | ||
507 | private final Map<RegionId, Region> lookup = new HashMap<>(); | 505 | private final Map<RegionId, Region> lookup = new HashMap<>(); |
508 | 506 | ||
... | @@ -549,14 +547,6 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -549,14 +547,6 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
549 | } | 547 | } |
550 | return Collections.emptySet(); | 548 | return Collections.emptySet(); |
551 | } | 549 | } |
552 | - | ||
553 | - @Override | ||
554 | - public void addListener(RegionListener listener) { | ||
555 | - } | ||
556 | - | ||
557 | - @Override | ||
558 | - public void removeListener(RegionListener listener) { | ||
559 | - } | ||
560 | } | 550 | } |
561 | 551 | ||
562 | 552 | ... | ... |
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 | +package org.onosproject.ui.impl.topo.model; | ||
18 | + | ||
19 | +import org.onosproject.net.DeviceId; | ||
20 | +import org.onosproject.net.HostId; | ||
21 | +import org.onosproject.net.region.Region; | ||
22 | +import org.onosproject.net.region.RegionId; | ||
23 | +import org.onosproject.net.region.RegionListener; | ||
24 | +import org.onosproject.net.region.RegionService; | ||
25 | + | ||
26 | +import java.util.Collections; | ||
27 | +import java.util.Set; | ||
28 | + | ||
29 | +/** | ||
30 | + * Adapter for {@link RegionService}. | ||
31 | + */ | ||
32 | +public class RegionServiceAdapter implements RegionService { | ||
33 | + @Override | ||
34 | + public void addListener(RegionListener listener) { | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public void removeListener(RegionListener listener) { | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public Set<Region> getRegions() { | ||
43 | + return Collections.emptySet(); | ||
44 | + } | ||
45 | + | ||
46 | + @Override | ||
47 | + public Region getRegion(RegionId regionId) { | ||
48 | + return null; | ||
49 | + } | ||
50 | + | ||
51 | + @Override | ||
52 | + public Region getRegionForDevice(DeviceId deviceId) { | ||
53 | + return null; | ||
54 | + } | ||
55 | + | ||
56 | + @Override | ||
57 | + public Set<DeviceId> getRegionDevices(RegionId regionId) { | ||
58 | + return Collections.emptySet(); | ||
59 | + } | ||
60 | + | ||
61 | + @Override | ||
62 | + public Set<HostId> getRegionHosts(RegionId regionId) { | ||
63 | + return Collections.emptySet(); | ||
64 | + } | ||
65 | +} |
-
Please register or login to post a comment