ONOS-4971: Synthetic Link Data -- WIP
- Enhancing UiRegion to capture the hierarchical (parent/child) relationships captured in the UiTopoLayouts. Change-Id: I152e0d52d4580b14b679f3387402077f16f61e6a
Showing
11 changed files
with
264 additions
and
6 deletions
... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.ui; | 16 | package org.onosproject.ui; |
17 | 17 | ||
18 | +import org.onosproject.net.region.RegionId; | ||
18 | import org.onosproject.ui.model.topo.UiTopoLayout; | 19 | import org.onosproject.ui.model.topo.UiTopoLayout; |
19 | import org.onosproject.ui.model.topo.UiTopoLayoutId; | 20 | import org.onosproject.ui.model.topo.UiTopoLayoutId; |
20 | 21 | ||
... | @@ -57,6 +58,15 @@ public interface UiTopoLayoutService { | ... | @@ -57,6 +58,15 @@ public interface UiTopoLayoutService { |
57 | UiTopoLayout getLayout(UiTopoLayoutId layoutId); | 58 | UiTopoLayout getLayout(UiTopoLayoutId layoutId); |
58 | 59 | ||
59 | /** | 60 | /** |
61 | + * Returns the layout which has the backing region identified by | ||
62 | + * the given region identifier. | ||
63 | + * | ||
64 | + * @param regionId region identifier | ||
65 | + * @return corresponding layout | ||
66 | + */ | ||
67 | + UiTopoLayout getLayout(RegionId regionId); | ||
68 | + | ||
69 | + /** | ||
60 | * Returns the set of peer layouts of the specified layout. That is, | 70 | * Returns the set of peer layouts of the specified layout. That is, |
61 | * those layouts that share the same parent. | 71 | * those layouts that share the same parent. |
62 | * | 72 | * | ... | ... |
... | @@ -24,11 +24,20 @@ import org.onosproject.net.host.HostService; | ... | @@ -24,11 +24,20 @@ import org.onosproject.net.host.HostService; |
24 | import org.onosproject.net.intent.IntentService; | 24 | import org.onosproject.net.intent.IntentService; |
25 | import org.onosproject.net.link.LinkService; | 25 | import org.onosproject.net.link.LinkService; |
26 | import org.onosproject.net.region.RegionService; | 26 | import org.onosproject.net.region.RegionService; |
27 | +import org.onosproject.ui.UiTopoLayoutService; | ||
27 | 28 | ||
28 | /** | 29 | /** |
29 | * A bundle of services to pass to elements that might need a reference to them. | 30 | * A bundle of services to pass to elements that might need a reference to them. |
30 | */ | 31 | */ |
31 | public interface ServiceBundle { | 32 | public interface ServiceBundle { |
33 | + | ||
34 | + /** | ||
35 | + * Reference to a UI Topology Layout service implementation. | ||
36 | + * | ||
37 | + * @return layout service | ||
38 | + */ | ||
39 | + UiTopoLayoutService layout(); | ||
40 | + | ||
32 | /** | 41 | /** |
33 | * Reference to a cluster service implementation. | 42 | * Reference to a cluster service implementation. |
34 | * | 43 | * | ... | ... |
... | @@ -61,6 +61,10 @@ public class UiRegion extends UiNode { | ... | @@ -61,6 +61,10 @@ public class UiRegion extends UiNode { |
61 | 61 | ||
62 | private final Region region; | 62 | private final Region region; |
63 | 63 | ||
64 | + // keep track of hierarchy (inferred from UiTopoLayoutService) | ||
65 | + private RegionId parent; | ||
66 | + private final Set<RegionId> kids = new HashSet<>(); | ||
67 | + | ||
64 | /** | 68 | /** |
65 | * Constructs a UI region, with a reference to the specified backing region. | 69 | * Constructs a UI region, with a reference to the specified backing region. |
66 | * | 70 | * |
... | @@ -103,6 +107,52 @@ public class UiRegion extends UiNode { | ... | @@ -103,6 +107,52 @@ public class UiRegion extends UiNode { |
103 | return region == null ? NULL_ID : region.id(); | 107 | return region == null ? NULL_ID : region.id(); |
104 | } | 108 | } |
105 | 109 | ||
110 | + /** | ||
111 | + * Returns the identity of the parent region. | ||
112 | + * | ||
113 | + * @return parent region ID | ||
114 | + */ | ||
115 | + public RegionId parent() { | ||
116 | + return parent; | ||
117 | + } | ||
118 | + | ||
119 | + /** | ||
120 | + * Returns true if this is the root (default) region. | ||
121 | + * | ||
122 | + * @return true if root region | ||
123 | + */ | ||
124 | + public boolean isRoot() { | ||
125 | + return id().equals(parent); | ||
126 | + } | ||
127 | + | ||
128 | + /** | ||
129 | + * Returns the identities of the child regions. | ||
130 | + * | ||
131 | + * @return child region IDs | ||
132 | + */ | ||
133 | + public Set<RegionId> children() { | ||
134 | + return ImmutableSet.copyOf(kids); | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * Sets the parent ID for this region. | ||
139 | + * | ||
140 | + * @param parentId parent ID | ||
141 | + */ | ||
142 | + public void setParent(RegionId parentId) { | ||
143 | + parent = parentId; | ||
144 | + } | ||
145 | + | ||
146 | + /** | ||
147 | + * Sets the children IDs for this region. | ||
148 | + * | ||
149 | + * @param children children IDs | ||
150 | + */ | ||
151 | + public void setChildren(Set<RegionId> children) { | ||
152 | + kids.clear(); | ||
153 | + kids.addAll(children); | ||
154 | + } | ||
155 | + | ||
106 | @Override | 156 | @Override |
107 | public String idAsString() { | 157 | public String idAsString() { |
108 | return id().toString(); | 158 | return id().toString(); |
... | @@ -138,6 +188,8 @@ public class UiRegion extends UiNode { | ... | @@ -138,6 +188,8 @@ public class UiRegion extends UiNode { |
138 | return toStringHelper(this) | 188 | return toStringHelper(this) |
139 | .add("id", id()) | 189 | .add("id", id()) |
140 | .add("name", name()) | 190 | .add("name", name()) |
191 | + .add("parent", parent) | ||
192 | + .add("kids", kids) | ||
141 | .add("devices", deviceIds) | 193 | .add("devices", deviceIds) |
142 | .add("#hosts", hostIds.size()) | 194 | .add("#hosts", hostIds.size()) |
143 | .add("#links", uiLinkIds.size()) | 195 | .add("#links", uiLinkIds.size()) | ... | ... |
... | @@ -68,13 +68,16 @@ public class UiTopoLayout { | ... | @@ -68,13 +68,16 @@ public class UiTopoLayout { |
68 | } | 68 | } |
69 | 69 | ||
70 | /** | 70 | /** |
71 | - * Returns the identifier of the backing region. Will be null if the | 71 | + * Returns the identifier of the backing region. If this is the default |
72 | - * region is null. | 72 | + * layout, the null-region ID will be returned, otherwise the ID of the |
73 | + * backing region for this layout will be returned; null in the case that | ||
74 | + * there is no backing region. | ||
73 | * | 75 | * |
74 | * @return backing region identifier | 76 | * @return backing region identifier |
75 | */ | 77 | */ |
76 | public RegionId regionId() { | 78 | public RegionId regionId() { |
77 | - return region == null ? null : region.id(); | 79 | + return isRoot() ? UiRegion.NULL_ID |
80 | + : (region == null ? null : region.id()); | ||
78 | } | 81 | } |
79 | 82 | ||
80 | /** | 83 | /** | ... | ... |
... | @@ -151,7 +151,8 @@ public class UiTopology extends UiElement { | ... | @@ -151,7 +151,8 @@ public class UiTopology extends UiElement { |
151 | 151 | ||
152 | 152 | ||
153 | /** | 153 | /** |
154 | - * Returns all regions in the model. | 154 | + * Returns all regions in the model (except the |
155 | + * {@link #nullRegion() null region}). | ||
155 | * | 156 | * |
156 | * @return all regions | 157 | * @return all regions |
157 | */ | 158 | */ |
... | @@ -177,7 +178,7 @@ public class UiTopology extends UiElement { | ... | @@ -177,7 +178,7 @@ public class UiTopology extends UiElement { |
177 | * @return corresponding UI region | 178 | * @return corresponding UI region |
178 | */ | 179 | */ |
179 | public UiRegion findRegion(RegionId id) { | 180 | public UiRegion findRegion(RegionId id) { |
180 | - return regionLookup.get(id); | 181 | + return UiRegion.NULL_ID.equals(id) ? nullRegion() : regionLookup.get(id); |
181 | } | 182 | } |
182 | 183 | ||
183 | /** | 184 | /** | ... | ... |
... | @@ -28,6 +28,7 @@ import org.onosproject.net.intent.IntentService; | ... | @@ -28,6 +28,7 @@ import org.onosproject.net.intent.IntentService; |
28 | import org.onosproject.net.link.LinkService; | 28 | import org.onosproject.net.link.LinkService; |
29 | import org.onosproject.net.region.RegionService; | 29 | import org.onosproject.net.region.RegionService; |
30 | import org.onosproject.ui.AbstractUiTest; | 30 | import org.onosproject.ui.AbstractUiTest; |
31 | +import org.onosproject.ui.UiTopoLayoutService; | ||
31 | 32 | ||
32 | /** | 33 | /** |
33 | * Base class for UI model unit tests. | 34 | * Base class for UI model unit tests. |
... | @@ -42,6 +43,11 @@ public class AbstractUiModelTest extends AbstractUiTest { | ... | @@ -42,6 +43,11 @@ public class AbstractUiModelTest extends AbstractUiTest { |
42 | protected static final ServiceBundle MOCK_SERVICES = | 43 | protected static final ServiceBundle MOCK_SERVICES = |
43 | new ServiceBundle() { | 44 | new ServiceBundle() { |
44 | @Override | 45 | @Override |
46 | + public UiTopoLayoutService layout() { | ||
47 | + return null; | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
45 | public ClusterService cluster() { | 51 | public ClusterService cluster() { |
46 | return MOCK_CLUSTER; | 52 | return MOCK_CLUSTER; |
47 | } | 53 | } | ... | ... |
... | @@ -24,17 +24,20 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -24,17 +24,20 @@ import org.apache.felix.scr.annotations.Reference; |
24 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 24 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
25 | import org.apache.felix.scr.annotations.Service; | 25 | import org.apache.felix.scr.annotations.Service; |
26 | import org.onlab.util.KryoNamespace; | 26 | import org.onlab.util.KryoNamespace; |
27 | +import org.onosproject.net.region.RegionId; | ||
27 | import org.onosproject.store.serializers.KryoNamespaces; | 28 | import org.onosproject.store.serializers.KryoNamespaces; |
28 | import org.onosproject.store.service.ConsistentMap; | 29 | import org.onosproject.store.service.ConsistentMap; |
29 | import org.onosproject.store.service.Serializer; | 30 | import org.onosproject.store.service.Serializer; |
30 | import org.onosproject.store.service.StorageService; | 31 | import org.onosproject.store.service.StorageService; |
31 | import org.onosproject.ui.UiTopoLayoutService; | 32 | import org.onosproject.ui.UiTopoLayoutService; |
33 | +import org.onosproject.ui.model.topo.UiRegion; | ||
32 | import org.onosproject.ui.model.topo.UiTopoLayout; | 34 | import org.onosproject.ui.model.topo.UiTopoLayout; |
33 | import org.onosproject.ui.model.topo.UiTopoLayoutId; | 35 | import org.onosproject.ui.model.topo.UiTopoLayoutId; |
34 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
35 | import org.slf4j.LoggerFactory; | 37 | import org.slf4j.LoggerFactory; |
36 | 38 | ||
37 | import java.util.Collections; | 39 | import java.util.Collections; |
40 | +import java.util.List; | ||
38 | import java.util.Map; | 41 | import java.util.Map; |
39 | import java.util.Objects; | 42 | import java.util.Objects; |
40 | import java.util.Set; | 43 | import java.util.Set; |
... | @@ -111,6 +114,18 @@ public class UiTopoLayoutManager implements UiTopoLayoutService { | ... | @@ -111,6 +114,18 @@ public class UiTopoLayoutManager implements UiTopoLayoutService { |
111 | } | 114 | } |
112 | 115 | ||
113 | @Override | 116 | @Override |
117 | + public UiTopoLayout getLayout(RegionId regionId) { | ||
118 | + if (regionId == null || regionId.equals(UiRegion.NULL_ID)) { | ||
119 | + return getRootLayout(); | ||
120 | + } | ||
121 | + | ||
122 | + List<UiTopoLayout> matchingLayouts = layoutMap.values().stream() | ||
123 | + .filter(l -> Objects.equals(regionId, l.regionId())) | ||
124 | + .collect(Collectors.toList()); | ||
125 | + return matchingLayouts.isEmpty() ? null : matchingLayouts.get(0); | ||
126 | + } | ||
127 | + | ||
128 | + @Override | ||
114 | public Set<UiTopoLayout> getPeerLayouts(UiTopoLayoutId layoutId) { | 129 | public Set<UiTopoLayout> getPeerLayouts(UiTopoLayoutId layoutId) { |
115 | checkNotNull(layoutId, ID_NULL); | 130 | checkNotNull(layoutId, ID_NULL); |
116 | 131 | ... | ... |
... | @@ -29,6 +29,7 @@ public class ListRegions extends AbstractElementCommand { | ... | @@ -29,6 +29,7 @@ public class ListRegions extends AbstractElementCommand { |
29 | @Override | 29 | @Override |
30 | protected void execute() { | 30 | protected void execute() { |
31 | UiSharedTopologyModel model = get(UiSharedTopologyModel.class); | 31 | UiSharedTopologyModel model = get(UiSharedTopologyModel.class); |
32 | + print("%s", model.getNullRegion()); | ||
32 | sorted(model.getRegions()).forEach(r -> print("%s", r)); | 33 | sorted(model.getRegions()).forEach(r -> print("%s", r)); |
33 | } | 34 | } |
34 | } | 35 | } | ... | ... |
... | @@ -29,6 +29,7 @@ import org.onosproject.net.HostLocation; | ... | @@ -29,6 +29,7 @@ import org.onosproject.net.HostLocation; |
29 | import org.onosproject.net.Link; | 29 | import org.onosproject.net.Link; |
30 | import org.onosproject.net.region.Region; | 30 | import org.onosproject.net.region.Region; |
31 | import org.onosproject.net.region.RegionId; | 31 | import org.onosproject.net.region.RegionId; |
32 | +import org.onosproject.ui.UiTopoLayoutService; | ||
32 | import org.onosproject.ui.model.ServiceBundle; | 33 | import org.onosproject.ui.model.ServiceBundle; |
33 | import org.onosproject.ui.model.topo.UiClusterMember; | 34 | import org.onosproject.ui.model.topo.UiClusterMember; |
34 | import org.onosproject.ui.model.topo.UiDevice; | 35 | import org.onosproject.ui.model.topo.UiDevice; |
... | @@ -37,6 +38,8 @@ import org.onosproject.ui.model.topo.UiHost; | ... | @@ -37,6 +38,8 @@ import org.onosproject.ui.model.topo.UiHost; |
37 | import org.onosproject.ui.model.topo.UiLink; | 38 | import org.onosproject.ui.model.topo.UiLink; |
38 | import org.onosproject.ui.model.topo.UiLinkId; | 39 | import org.onosproject.ui.model.topo.UiLinkId; |
39 | import org.onosproject.ui.model.topo.UiRegion; | 40 | import org.onosproject.ui.model.topo.UiRegion; |
41 | +import org.onosproject.ui.model.topo.UiTopoLayout; | ||
42 | +import org.onosproject.ui.model.topo.UiTopoLayoutId; | ||
40 | import org.onosproject.ui.model.topo.UiTopology; | 43 | import org.onosproject.ui.model.topo.UiTopology; |
41 | import org.slf4j.Logger; | 44 | import org.slf4j.Logger; |
42 | import org.slf4j.LoggerFactory; | 45 | import org.slf4j.LoggerFactory; |
... | @@ -202,6 +205,34 @@ class ModelCache { | ... | @@ -202,6 +205,34 @@ class ModelCache { |
202 | 205 | ||
203 | // Make sure the region object refers to the devices | 206 | // Make sure the region object refers to the devices |
204 | region.reconcileDevices(deviceIds); | 207 | region.reconcileDevices(deviceIds); |
208 | + | ||
209 | + fixupContainmentHierarchy(region); | ||
210 | + } | ||
211 | + | ||
212 | + private void fixupContainmentHierarchy(UiRegion region) { | ||
213 | + UiTopoLayoutService ls = services.layout(); | ||
214 | + RegionId regionId = region.id(); | ||
215 | + | ||
216 | + UiTopoLayout layout = ls.getLayout(regionId); | ||
217 | + if (layout == null) { | ||
218 | + // no layout backed by this region | ||
219 | + log.warn("No layout backed by region {}", regionId); | ||
220 | + return; | ||
221 | + } | ||
222 | + | ||
223 | + UiTopoLayoutId layoutId = layout.id(); | ||
224 | + | ||
225 | + if (!layout.isRoot()) { | ||
226 | + UiTopoLayoutId parentId = layout.parent(); | ||
227 | + UiTopoLayout parentLayout = ls.getLayout(parentId); | ||
228 | + RegionId parentRegionId = parentLayout.regionId(); | ||
229 | + region.setParent(parentRegionId); | ||
230 | + } | ||
231 | + | ||
232 | + Set<UiTopoLayout> kids = ls.getChildren(layoutId); | ||
233 | + Set<RegionId> kidRegionIds = new HashSet<>(kids.size()); | ||
234 | + kids.forEach(k -> kidRegionIds.add(k.regionId())); | ||
235 | + region.setChildren(kidRegionIds); | ||
205 | } | 236 | } |
206 | 237 | ||
207 | private void loadRegions() { | 238 | private void loadRegions() { |
... | @@ -478,7 +509,11 @@ class ModelCache { | ... | @@ -478,7 +509,11 @@ class ModelCache { |
478 | public void refresh() { | 509 | public void refresh() { |
479 | // fix up internal linkages if they aren't correct | 510 | // fix up internal linkages if they aren't correct |
480 | 511 | ||
481 | - // at the moment, this is making sure devices are in the correct region | 512 | + // make sure regions reflect layout containment hierarchy |
513 | + fixupContainmentHierarchy(uiTopology.nullRegion()); | ||
514 | + uiTopology.allRegions().forEach(this::fixupContainmentHierarchy); | ||
515 | + | ||
516 | + // make sure devices are in the correct region | ||
482 | Set<UiDevice> allDevices = uiTopology.allDevices(); | 517 | Set<UiDevice> allDevices = uiTopology.allDevices(); |
483 | 518 | ||
484 | services.region().getRegions().forEach(r -> { | 519 | services.region().getRegions().forEach(r -> { | ... | ... |
... | @@ -60,6 +60,7 @@ import org.onosproject.net.region.RegionListener; | ... | @@ -60,6 +60,7 @@ import org.onosproject.net.region.RegionListener; |
60 | import org.onosproject.net.region.RegionService; | 60 | import org.onosproject.net.region.RegionService; |
61 | import org.onosproject.net.statistic.StatisticService; | 61 | import org.onosproject.net.statistic.StatisticService; |
62 | import org.onosproject.net.topology.TopologyService; | 62 | import org.onosproject.net.topology.TopologyService; |
63 | +import org.onosproject.ui.UiTopoLayoutService; | ||
63 | import org.onosproject.ui.impl.topo.UiTopoSession; | 64 | import org.onosproject.ui.impl.topo.UiTopoSession; |
64 | import org.onosproject.ui.model.ServiceBundle; | 65 | import org.onosproject.ui.model.ServiceBundle; |
65 | import org.onosproject.ui.model.topo.UiClusterMember; | 66 | import org.onosproject.ui.model.topo.UiClusterMember; |
... | @@ -87,6 +88,9 @@ public final class UiSharedTopologyModel | ... | @@ -87,6 +88,9 @@ public final class UiSharedTopologyModel |
87 | LoggerFactory.getLogger(UiSharedTopologyModel.class); | 88 | LoggerFactory.getLogger(UiSharedTopologyModel.class); |
88 | 89 | ||
89 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 90 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
91 | + private UiTopoLayoutService layoutService; | ||
92 | + | ||
93 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
90 | private ClusterService clusterService; | 94 | private ClusterService clusterService; |
91 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 95 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
92 | private MastershipService mastershipService; | 96 | private MastershipService mastershipService; |
... | @@ -282,6 +286,11 @@ public final class UiSharedTopologyModel | ... | @@ -282,6 +286,11 @@ public final class UiSharedTopologyModel |
282 | */ | 286 | */ |
283 | private class DefaultServiceBundle implements ServiceBundle { | 287 | private class DefaultServiceBundle implements ServiceBundle { |
284 | @Override | 288 | @Override |
289 | + public UiTopoLayoutService layout() { | ||
290 | + return layoutService; | ||
291 | + } | ||
292 | + | ||
293 | + @Override | ||
285 | public ClusterService cluster() { | 294 | public ClusterService cluster() { |
286 | return clusterService; | 295 | return clusterService; |
287 | } | 296 | } | ... | ... |
... | @@ -54,8 +54,11 @@ import org.onosproject.net.region.Region; | ... | @@ -54,8 +54,11 @@ 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; | 55 | import org.onosproject.net.region.RegionListener; |
56 | import org.onosproject.net.region.RegionService; | 56 | import org.onosproject.net.region.RegionService; |
57 | +import org.onosproject.ui.UiTopoLayoutService; | ||
57 | import org.onosproject.ui.impl.AbstractUiImplTest; | 58 | import org.onosproject.ui.impl.AbstractUiImplTest; |
58 | import org.onosproject.ui.model.ServiceBundle; | 59 | import org.onosproject.ui.model.ServiceBundle; |
60 | +import org.onosproject.ui.model.topo.UiTopoLayout; | ||
61 | +import org.onosproject.ui.model.topo.UiTopoLayoutId; | ||
59 | 62 | ||
60 | import java.util.ArrayList; | 63 | import java.util.ArrayList; |
61 | import java.util.Collections; | 64 | import java.util.Collections; |
... | @@ -69,6 +72,7 @@ import static org.onosproject.cluster.NodeId.nodeId; | ... | @@ -69,6 +72,7 @@ import static org.onosproject.cluster.NodeId.nodeId; |
69 | import static org.onosproject.net.DeviceId.deviceId; | 72 | import static org.onosproject.net.DeviceId.deviceId; |
70 | import static org.onosproject.net.HostId.hostId; | 73 | import static org.onosproject.net.HostId.hostId; |
71 | import static org.onosproject.net.PortNumber.portNumber; | 74 | import static org.onosproject.net.PortNumber.portNumber; |
75 | +import static org.onosproject.ui.model.topo.UiTopoLayoutId.layoutId; | ||
72 | 76 | ||
73 | /** | 77 | /** |
74 | * Base class for model test classes. | 78 | * Base class for model test classes. |
... | @@ -90,6 +94,12 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -90,6 +94,12 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
90 | 94 | ||
91 | Twelve hosts (two per D4 ... D9) H4a, H4b, H5a, H5b, ... | 95 | Twelve hosts (two per D4 ... D9) H4a, H4b, H5a, H5b, ... |
92 | 96 | ||
97 | + Layouts: | ||
98 | + LROOT : (default) | ||
99 | + +-- L1 : R1 | ||
100 | + +-- L2 : R2 | ||
101 | + +-- L3 : R3 | ||
102 | + | ||
93 | Regions: | 103 | Regions: |
94 | R1 : D1, D2, D3 | 104 | R1 : D1, D2, D3 |
95 | R2 : D4, D5, D6 | 105 | R2 : D4, D5, D6 |
... | @@ -136,6 +146,27 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -136,6 +146,27 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
136 | protected static final Set<Region> REGION_SET = | 146 | protected static final Set<Region> REGION_SET = |
137 | ImmutableSet.of(REGION_1, REGION_2, REGION_3); | 147 | ImmutableSet.of(REGION_1, REGION_2, REGION_3); |
138 | 148 | ||
149 | + protected static final String LROOT = "LROOT"; | ||
150 | + protected static final String L1 = "L1"; | ||
151 | + protected static final String L2 = "L2"; | ||
152 | + protected static final String L3 = "L3"; | ||
153 | + | ||
154 | + protected static final UiTopoLayout LAYOUT_ROOT = layout(LROOT, null, null); | ||
155 | + protected static final UiTopoLayout LAYOUT_1 = layout(L1, REGION_1, LROOT); | ||
156 | + protected static final UiTopoLayout LAYOUT_2 = layout(L2, REGION_2, LROOT); | ||
157 | + protected static final UiTopoLayout LAYOUT_3 = layout(L3, REGION_3, LROOT); | ||
158 | + | ||
159 | + protected static final Set<UiTopoLayout> LAYOUT_SET = | ||
160 | + ImmutableSet.of(LAYOUT_ROOT, LAYOUT_1, LAYOUT_2, LAYOUT_3); | ||
161 | + protected static final Set<UiTopoLayout> ROOT_KIDS = | ||
162 | + ImmutableSet.of(LAYOUT_1, LAYOUT_2, LAYOUT_3); | ||
163 | + protected static final Set<UiTopoLayout> PEERS_OF_1 = | ||
164 | + ImmutableSet.of(LAYOUT_2, LAYOUT_3); | ||
165 | + protected static final Set<UiTopoLayout> PEERS_OF_2 = | ||
166 | + ImmutableSet.of(LAYOUT_1, LAYOUT_3); | ||
167 | + protected static final Set<UiTopoLayout> PEERS_OF_3 = | ||
168 | + ImmutableSet.of(LAYOUT_1, LAYOUT_2); | ||
169 | + | ||
139 | protected static final String D1 = "d1"; | 170 | protected static final String D1 = "d1"; |
140 | protected static final String D2 = "d2"; | 171 | protected static final String D2 = "d2"; |
141 | protected static final String D3 = "d3"; | 172 | protected static final String D3 = "d3"; |
... | @@ -222,6 +253,21 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -222,6 +253,21 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
222 | } | 253 | } |
223 | 254 | ||
224 | /** | 255 | /** |
256 | + * Returns UI topology layout instance with the specified parameters. | ||
257 | + * | ||
258 | + * @param layoutId the layout ID | ||
259 | + * @param region the backing region | ||
260 | + * @param parentId the parent layout ID | ||
261 | + * @return layout instance | ||
262 | + */ | ||
263 | + protected static UiTopoLayout layout(String layoutId, Region region, | ||
264 | + String parentId) { | ||
265 | + UiTopoLayoutId pid = parentId == null | ||
266 | + ? UiTopoLayoutId.DEFAULT_ID : layoutId(parentId); | ||
267 | + return new UiTopoLayout(layoutId(layoutId), region, pid); | ||
268 | + } | ||
269 | + | ||
270 | + /** | ||
225 | * Returns a region instance with specified parameters. | 271 | * Returns a region instance with specified parameters. |
226 | * | 272 | * |
227 | * @param id region id | 273 | * @param id region id |
... | @@ -255,6 +301,11 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -255,6 +301,11 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
255 | protected static final ServiceBundle MOCK_SERVICES = | 301 | protected static final ServiceBundle MOCK_SERVICES = |
256 | new ServiceBundle() { | 302 | new ServiceBundle() { |
257 | @Override | 303 | @Override |
304 | + public UiTopoLayoutService layout() { | ||
305 | + return MOCK_LAYOUT; | ||
306 | + } | ||
307 | + | ||
308 | + @Override | ||
258 | public ClusterService cluster() { | 309 | public ClusterService cluster() { |
259 | return MOCK_CLUSTER; | 310 | return MOCK_CLUSTER; |
260 | } | 311 | } |
... | @@ -297,6 +348,7 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -297,6 +348,7 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
297 | 348 | ||
298 | private static final ClusterService MOCK_CLUSTER = new MockClusterService(); | 349 | private static final ClusterService MOCK_CLUSTER = new MockClusterService(); |
299 | private static final MastershipService MOCK_MASTER = new MockMasterService(); | 350 | private static final MastershipService MOCK_MASTER = new MockMasterService(); |
351 | + private static final UiTopoLayoutService MOCK_LAYOUT = new MockLayoutService(); | ||
300 | private static final RegionService MOCK_REGION = new MockRegionService(); | 352 | private static final RegionService MOCK_REGION = new MockRegionService(); |
301 | private static final DeviceService MOCK_DEVICE = new MockDeviceService(); | 353 | private static final DeviceService MOCK_DEVICE = new MockDeviceService(); |
302 | private static final LinkService MOCK_LINK = new MockLinkService(); | 354 | private static final LinkService MOCK_LINK = new MockLinkService(); |
... | @@ -384,6 +436,71 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { | ... | @@ -384,6 +436,71 @@ abstract class AbstractTopoModelTest extends AbstractUiImplTest { |
384 | } | 436 | } |
385 | } | 437 | } |
386 | 438 | ||
439 | + // TODO: consider implementing UiTopoLayoutServiceAdapter and extending that here | ||
440 | + private static class MockLayoutService implements UiTopoLayoutService { | ||
441 | + private final Map<UiTopoLayoutId, UiTopoLayout> map = new HashMap<>(); | ||
442 | + private final Map<UiTopoLayoutId, Set<UiTopoLayout>> peers = new HashMap<>(); | ||
443 | + private final Map<RegionId, UiTopoLayout> byRegion = new HashMap<>(); | ||
444 | + | ||
445 | + MockLayoutService() { | ||
446 | + map.put(LAYOUT_ROOT.id(), LAYOUT_ROOT); | ||
447 | + map.put(LAYOUT_1.id(), LAYOUT_1); | ||
448 | + map.put(LAYOUT_2.id(), LAYOUT_2); | ||
449 | + map.put(LAYOUT_3.id(), LAYOUT_3); | ||
450 | + | ||
451 | + peers.put(LAYOUT_ROOT.id(), ImmutableSet.of()); | ||
452 | + peers.put(LAYOUT_1.id(), ImmutableSet.of(LAYOUT_2, LAYOUT_3)); | ||
453 | + peers.put(LAYOUT_2.id(), ImmutableSet.of(LAYOUT_1, LAYOUT_3)); | ||
454 | + peers.put(LAYOUT_3.id(), ImmutableSet.of(LAYOUT_1, LAYOUT_2)); | ||
455 | + | ||
456 | + byRegion.put(REGION_1.id(), LAYOUT_1); | ||
457 | + byRegion.put(REGION_2.id(), LAYOUT_2); | ||
458 | + byRegion.put(REGION_3.id(), LAYOUT_3); | ||
459 | + } | ||
460 | + | ||
461 | + @Override | ||
462 | + public UiTopoLayout getRootLayout() { | ||
463 | + return LAYOUT_ROOT; | ||
464 | + } | ||
465 | + | ||
466 | + @Override | ||
467 | + public Set<UiTopoLayout> getLayouts() { | ||
468 | + return LAYOUT_SET; | ||
469 | + } | ||
470 | + | ||
471 | + @Override | ||
472 | + public boolean addLayout(UiTopoLayout layout) { | ||
473 | + return false; | ||
474 | + } | ||
475 | + | ||
476 | + @Override | ||
477 | + public UiTopoLayout getLayout(UiTopoLayoutId layoutId) { | ||
478 | + return map.get(layoutId); | ||
479 | + } | ||
480 | + | ||
481 | + @Override | ||
482 | + public UiTopoLayout getLayout(RegionId regionId) { | ||
483 | + return byRegion.get(regionId); | ||
484 | + } | ||
485 | + | ||
486 | + @Override | ||
487 | + public Set<UiTopoLayout> getPeerLayouts(UiTopoLayoutId layoutId) { | ||
488 | + return peers.get(layoutId); | ||
489 | + } | ||
490 | + | ||
491 | + @Override | ||
492 | + public Set<UiTopoLayout> getChildren(UiTopoLayoutId layoutId) { | ||
493 | + return LAYOUT_ROOT.id().equals(layoutId) | ||
494 | + ? ROOT_KIDS | ||
495 | + : Collections.emptySet(); | ||
496 | + } | ||
497 | + | ||
498 | + @Override | ||
499 | + public boolean removeLayout(UiTopoLayout layout) { | ||
500 | + return false; | ||
501 | + } | ||
502 | + } | ||
503 | + | ||
387 | // TODO: consider implementing RegionServiceAdapter and extending that here | 504 | // TODO: consider implementing RegionServiceAdapter and extending that here |
388 | private static class MockRegionService implements RegionService { | 505 | private static class MockRegionService implements RegionService { |
389 | 506 | ... | ... |
-
Please register or login to post a comment