Simon Hunt
Committed by Gerrit Code Review

Added breadcrumbs array to topo2CurrentLayout response.

Included Region name in "closed region" data structures.

Change-Id: I1d4c223255b7ea8239f38c63d4caebe1bdeddf32
...@@ -29,6 +29,7 @@ import java.util.List; ...@@ -29,6 +29,7 @@ import java.util.List;
29 import java.util.Set; 29 import java.util.Set;
30 30
31 import static com.google.common.base.MoreObjects.toStringHelper; 31 import static com.google.common.base.MoreObjects.toStringHelper;
32 +import static com.google.common.base.Strings.isNullOrEmpty;
32 import static org.onosproject.net.region.RegionId.regionId; 33 import static org.onosproject.net.region.RegionId.regionId;
33 34
34 /** 35 /**
...@@ -36,7 +37,8 @@ import static org.onosproject.net.region.RegionId.regionId; ...@@ -36,7 +37,8 @@ import static org.onosproject.net.region.RegionId.regionId;
36 */ 37 */
37 public class UiRegion extends UiNode { 38 public class UiRegion extends UiNode {
38 39
39 - private static final String NULL_NAME = "<null-region>"; 40 + private static final String NULL_NAME = "(root)";
41 + private static final String NO_NAME = "???";
40 42
41 /** 43 /**
42 * The identifier for the null-region. That is, a container for devices, 44 * The identifier for the null-region. That is, a container for devices,
...@@ -271,4 +273,20 @@ public class UiRegion extends UiNode { ...@@ -271,4 +273,20 @@ public class UiRegion extends UiNode {
271 public List<String> layerOrder() { 273 public List<String> layerOrder() {
272 return Collections.unmodifiableList(layerOrder); 274 return Collections.unmodifiableList(layerOrder);
273 } 275 }
276 +
277 + /**
278 + * Guarantees to return a string for the name of the specified region.
279 + * If region is null, we return the null region name, else we return
280 + * the name as configured on the region.
281 + *
282 + * @param region the region whose name we require
283 + * @return the region's name
284 + */
285 + public static String safeName(Region region) {
286 + if (region == null) {
287 + return NULL_NAME;
288 + }
289 + String name = region.name();
290 + return isNullOrEmpty(name) ? NO_NAME : name;
291 + }
274 } 292 }
......
...@@ -34,7 +34,6 @@ import org.onosproject.net.flow.FlowRuleService; ...@@ -34,7 +34,6 @@ import org.onosproject.net.flow.FlowRuleService;
34 import org.onosproject.net.host.HostService; 34 import org.onosproject.net.host.HostService;
35 import org.onosproject.net.intent.IntentService; 35 import org.onosproject.net.intent.IntentService;
36 import org.onosproject.net.link.LinkService; 36 import org.onosproject.net.link.LinkService;
37 -import org.onosproject.net.region.Region;
38 import org.onosproject.net.statistic.StatisticService; 37 import org.onosproject.net.statistic.StatisticService;
39 import org.onosproject.net.topology.TopologyService; 38 import org.onosproject.net.topology.TopologyService;
40 import org.onosproject.ui.model.topo.UiClusterMember; 39 import org.onosproject.ui.model.topo.UiClusterMember;
...@@ -170,21 +169,33 @@ class Topo2Jsonifier { ...@@ -170,21 +169,33 @@ class Topo2Jsonifier {
170 169
171 /** 170 /**
172 * Returns a JSON representation of the layout to use for displaying in 171 * Returns a JSON representation of the layout to use for displaying in
173 - * the topology view. 172 + * the topology view. The identifiers and names of regions from the
173 + * current to the root is included, so that the bread-crumb widget can
174 + * be rendered.
174 * 175 *
175 * @param layout the layout to transform 176 * @param layout the layout to transform
177 + * @param crumbs list of layouts in bread-crumb order
176 * @return a JSON representation of the data 178 * @return a JSON representation of the data
177 */ 179 */
178 - ObjectNode layout(UiTopoLayout layout) { 180 + ObjectNode layout(UiTopoLayout layout, List<UiTopoLayout> crumbs) {
179 - return objectNode() 181 + ObjectNode result = objectNode()
180 .put("id", layout.id().toString()) 182 .put("id", layout.id().toString())
181 .put("parent", nullIsEmpty(layout.parent())) 183 .put("parent", nullIsEmpty(layout.parent()))
182 .put("region", nullIsEmpty(layout.regionId())) 184 .put("region", nullIsEmpty(layout.regionId()))
183 - .put("regionName", regionName(layout.region())); 185 + .put("regionName", UiRegion.safeName(layout.region()));
186 + addCrumbs(result, crumbs);
187 + return result;
184 } 188 }
185 189
186 - private String regionName(Region region) { 190 + private void addCrumbs(ObjectNode result, List<UiTopoLayout> crumbs) {
187 - return region == null ? "" : region.name(); 191 + ArrayNode trail = arrayNode();
192 + crumbs.forEach(c -> {
193 + ObjectNode n = objectNode()
194 + .put("id", c.regionId().toString())
195 + .put("name", UiRegion.safeName(c.region()));
196 + trail.add(n);
197 + });
198 + result.set("crumbs", trail);
188 } 199 }
189 200
190 /** 201 /**
...@@ -364,6 +375,7 @@ class Topo2Jsonifier { ...@@ -364,6 +375,7 @@ class Topo2Jsonifier {
364 private ObjectNode jsonClosedRegion(UiRegion region) { 375 private ObjectNode jsonClosedRegion(UiRegion region) {
365 return objectNode() 376 return objectNode()
366 .put("id", region.idAsString()) 377 .put("id", region.idAsString())
378 + .put("name", region.name())
367 .put("nodeType", REGION) 379 .put("nodeType", REGION)
368 .put("nDevs", region.deviceCount()); 380 .put("nDevs", region.deviceCount());
369 // TODO: complete closed-region details 381 // TODO: complete closed-region details
......
...@@ -118,7 +118,8 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { ...@@ -118,7 +118,8 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
118 118
119 // this is the layout that the user has chosen to display 119 // this is the layout that the user has chosen to display
120 UiTopoLayout currentLayout = topoSession.currentLayout(); 120 UiTopoLayout currentLayout = topoSession.currentLayout();
121 - sendMessage(CURRENT_LAYOUT, t2json.layout(currentLayout)); 121 + List<UiTopoLayout> crumbs = topoSession.breadCrumbs();
122 + sendMessage(CURRENT_LAYOUT, t2json.layout(currentLayout, crumbs));
122 123
123 // this is the region that is associated with the current layout 124 // this is the region that is associated with the current layout
124 // this message includes details of the sub-regions, devices, 125 // this message includes details of the sub-regions, devices,
......
...@@ -30,6 +30,7 @@ import org.onosproject.ui.model.topo.UiTopoLayout; ...@@ -30,6 +30,7 @@ import org.onosproject.ui.model.topo.UiTopoLayout;
30 import org.slf4j.Logger; 30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory; 31 import org.slf4j.LoggerFactory;
32 32
33 +import java.util.ArrayList;
33 import java.util.HashSet; 34 import java.util.HashSet;
34 import java.util.List; 35 import java.util.List;
35 import java.util.Set; 36 import java.util.Set;
...@@ -134,6 +135,25 @@ public class UiTopoSession implements UiModelListener { ...@@ -134,6 +135,25 @@ public class UiTopoSession implements UiModelListener {
134 } 135 }
135 136
136 /** 137 /**
138 + * Returns the breadcrumb trail from current layout to root. That is,
139 + * element 0 of the list will be the current layout; the last element
140 + * of the list will be the root layout. This list is guaranteed to have
141 + * size of at least 1.
142 + *
143 + * @return breadcrumb trail
144 + */
145 + public List<UiTopoLayout> breadCrumbs() {
146 + UiTopoLayout current = currentLayout;
147 + List<UiTopoLayout> crumbs = new ArrayList<>();
148 + crumbs.add(current);
149 + while (!current.isRoot()) {
150 + current = layoutService.getLayout(current.parent());
151 + crumbs.add(current);
152 + }
153 + return crumbs;
154 + }
155 +
156 + /**
137 * Changes the current layout context to the specified layout. 157 * Changes the current layout context to the specified layout.
138 * 158 *
139 * @param topoLayout new topology layout context 159 * @param topoLayout new topology layout context
......