GUI -- Beginnings of structure for topology Overlay API.
- Re-implemented RequestSummary / ShowSummary in Alt implementation. Change-Id: Idb86c7bf3ede8f8815abcb488bbf9b0a7041ef79
Showing
12 changed files
with
577 additions
and
13 deletions
| ... | @@ -56,6 +56,7 @@ public abstract class RequestHandler { | ... | @@ -56,6 +56,7 @@ public abstract class RequestHandler { |
| 56 | * @param sid message sequence identifier | 56 | * @param sid message sequence identifier |
| 57 | * @param payload request message payload | 57 | * @param payload request message payload |
| 58 | */ | 58 | */ |
| 59 | + // TODO: remove sid from signature | ||
| 59 | public abstract void process(long sid, ObjectNode payload); | 60 | public abstract void process(long sid, ObjectNode payload); |
| 60 | 61 | ||
| 61 | 62 | ... | ... |
| ... | @@ -18,6 +18,8 @@ package org.onosproject.ui; | ... | @@ -18,6 +18,8 @@ package org.onosproject.ui; |
| 18 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
| 20 | import org.onlab.osgi.ServiceDirectory; | 20 | import org.onlab.osgi.ServiceDirectory; |
| 21 | +import org.slf4j.Logger; | ||
| 22 | +import org.slf4j.LoggerFactory; | ||
| 21 | 23 | ||
| 22 | import java.util.Collection; | 24 | import java.util.Collection; |
| 23 | import java.util.Collections; | 25 | import java.util.Collections; |
| ... | @@ -46,6 +48,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -46,6 +48,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 46 | */ | 48 | */ |
| 47 | public abstract class UiMessageHandler { | 49 | public abstract class UiMessageHandler { |
| 48 | 50 | ||
| 51 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
| 49 | private final Map<String, RequestHandler> handlerMap = new HashMap<>(); | 52 | private final Map<String, RequestHandler> handlerMap = new HashMap<>(); |
| 50 | 53 | ||
| 51 | private UiConnection connection; | 54 | private UiConnection connection; |
| ... | @@ -56,7 +59,6 @@ public abstract class UiMessageHandler { | ... | @@ -56,7 +59,6 @@ public abstract class UiMessageHandler { |
| 56 | */ | 59 | */ |
| 57 | protected final ObjectMapper mapper = new ObjectMapper(); | 60 | protected final ObjectMapper mapper = new ObjectMapper(); |
| 58 | 61 | ||
| 59 | - | ||
| 60 | /** | 62 | /** |
| 61 | * Subclasses must return the collection of handlers for the | 63 | * Subclasses must return the collection of handlers for the |
| 62 | * message types they handle. | 64 | * message types they handle. |
| ... | @@ -82,6 +84,7 @@ public abstract class UiMessageHandler { | ... | @@ -82,6 +84,7 @@ public abstract class UiMessageHandler { |
| 82 | */ | 84 | */ |
| 83 | public void process(ObjectNode message) { | 85 | public void process(ObjectNode message) { |
| 84 | String type = JsonUtils.eventType(message); | 86 | String type = JsonUtils.eventType(message); |
| 87 | + // TODO: remove sid | ||
| 85 | long sid = JsonUtils.sid(message); | 88 | long sid = JsonUtils.sid(message); |
| 86 | ObjectNode payload = JsonUtils.payload(message); | 89 | ObjectNode payload = JsonUtils.payload(message); |
| 87 | exec(type, sid, payload); | 90 | exec(type, sid, payload); |
| ... | @@ -94,9 +97,11 @@ public abstract class UiMessageHandler { | ... | @@ -94,9 +97,11 @@ public abstract class UiMessageHandler { |
| 94 | * @param sid sequence identifier | 97 | * @param sid sequence identifier |
| 95 | * @param payload message payload | 98 | * @param payload message payload |
| 96 | */ | 99 | */ |
| 100 | + // TODO: remove sid from signature | ||
| 97 | void exec(String eventType, long sid, ObjectNode payload) { | 101 | void exec(String eventType, long sid, ObjectNode payload) { |
| 98 | RequestHandler handler = handlerMap.get(eventType); | 102 | RequestHandler handler = handlerMap.get(eventType); |
| 99 | if (handler != null) { | 103 | if (handler != null) { |
| 104 | + log.debug("process {} event...", eventType); | ||
| 100 | handler.process(sid, payload); | 105 | handler.process(sid, payload); |
| 101 | } | 106 | } |
| 102 | } | 107 | } | ... | ... |
| ... | @@ -19,29 +19,40 @@ package org.onosproject.ui.impl; | ... | @@ -19,29 +19,40 @@ package org.onosproject.ui.impl; |
| 19 | 19 | ||
| 20 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
| 21 | import com.google.common.collect.ImmutableSet; | 21 | import com.google.common.collect.ImmutableSet; |
| 22 | +import com.google.common.collect.Maps; | ||
| 22 | import org.onlab.osgi.ServiceDirectory; | 23 | import org.onlab.osgi.ServiceDirectory; |
| 23 | import org.onosproject.core.CoreService; | 24 | import org.onosproject.core.CoreService; |
| 25 | +import org.onosproject.ui.JsonUtils; | ||
| 24 | import org.onosproject.ui.RequestHandler; | 26 | import org.onosproject.ui.RequestHandler; |
| 25 | import org.onosproject.ui.UiConnection; | 27 | import org.onosproject.ui.UiConnection; |
| 26 | import org.onosproject.ui.UiMessageHandler; | 28 | import org.onosproject.ui.UiMessageHandler; |
| 29 | +import org.onosproject.ui.impl.topo.OverlayService; | ||
| 30 | +import org.onosproject.ui.impl.topo.SummaryData; | ||
| 27 | import org.onosproject.ui.impl.topo.TopoUiEvent; | 31 | import org.onosproject.ui.impl.topo.TopoUiEvent; |
| 28 | import org.onosproject.ui.impl.topo.TopoUiListener; | 32 | import org.onosproject.ui.impl.topo.TopoUiListener; |
| 29 | import org.onosproject.ui.impl.topo.TopoUiModelService; | 33 | import org.onosproject.ui.impl.topo.TopoUiModelService; |
| 34 | +import org.onosproject.ui.impl.topo.overlay.AbstractSummaryGenerator; | ||
| 35 | +import org.onosproject.ui.impl.topo.overlay.SummaryGenerator; | ||
| 30 | import org.slf4j.Logger; | 36 | import org.slf4j.Logger; |
| 31 | import org.slf4j.LoggerFactory; | 37 | import org.slf4j.LoggerFactory; |
| 32 | 38 | ||
| 33 | import java.util.Collection; | 39 | import java.util.Collection; |
| 40 | +import java.util.HashMap; | ||
| 41 | +import java.util.Map; | ||
| 34 | 42 | ||
| 35 | import static com.google.common.base.Preconditions.checkNotNull; | 43 | import static com.google.common.base.Preconditions.checkNotNull; |
| 44 | +import static org.onosproject.ui.impl.topo.TopoUiEvent.Type.SUMMARY_UPDATE; | ||
| 36 | 45 | ||
| 37 | /** | 46 | /** |
| 38 | * Facility for handling inbound messages from the topology view, and | 47 | * Facility for handling inbound messages from the topology view, and |
| 39 | * generating outbound messages for the same. | 48 | * generating outbound messages for the same. |
| 40 | */ | 49 | */ |
| 41 | -public class AltTopoViewMessageHandler extends UiMessageHandler { | 50 | +public class AltTopoViewMessageHandler extends UiMessageHandler |
| 51 | + implements OverlayService { | ||
| 42 | 52 | ||
| 43 | private static final String TOPO_START = "topoStart"; | 53 | private static final String TOPO_START = "topoStart"; |
| 44 | private static final String TOPO_STOP = "topoStop"; | 54 | private static final String TOPO_STOP = "topoStop"; |
| 55 | + private static final String REQ_SUMMARY = "requestSummary"; | ||
| 45 | 56 | ||
| 46 | private final Logger log = LoggerFactory.getLogger(getClass()); | 57 | private final Logger log = LoggerFactory.getLogger(getClass()); |
| 47 | 58 | ||
| ... | @@ -50,6 +61,9 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -50,6 +61,9 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 50 | 61 | ||
| 51 | private TopoUiListener modelListener; | 62 | private TopoUiListener modelListener; |
| 52 | private String version; | 63 | private String version; |
| 64 | + private SummaryGenerator defaultSummaryGenerator; | ||
| 65 | + private SummaryGenerator currentSummaryGenerator; | ||
| 66 | + | ||
| 53 | 67 | ||
| 54 | private boolean topoActive = false; | 68 | private boolean topoActive = false; |
| 55 | 69 | ||
| ... | @@ -58,9 +72,12 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -58,9 +72,12 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 58 | super.init(connection, directory); | 72 | super.init(connection, directory); |
| 59 | this.directory = checkNotNull(directory, "Directory cannot be null"); | 73 | this.directory = checkNotNull(directory, "Directory cannot be null"); |
| 60 | modelService = directory.get(TopoUiModelService.class); | 74 | modelService = directory.get(TopoUiModelService.class); |
| 75 | + defaultSummaryGenerator = new DefSummaryGenerator("node", "ONOS Summary"); | ||
| 61 | 76 | ||
| 77 | + bindEventHandlers(); | ||
| 62 | modelListener = new ModelListener(); | 78 | modelListener = new ModelListener(); |
| 63 | version = getVersion(); | 79 | version = getVersion(); |
| 80 | + currentSummaryGenerator = defaultSummaryGenerator; | ||
| 64 | } | 81 | } |
| 65 | 82 | ||
| 66 | 83 | ||
| ... | @@ -74,11 +91,33 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -74,11 +91,33 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 74 | protected Collection<RequestHandler> getHandlers() { | 91 | protected Collection<RequestHandler> getHandlers() { |
| 75 | return ImmutableSet.of( | 92 | return ImmutableSet.of( |
| 76 | new TopoStart(), | 93 | new TopoStart(), |
| 77 | - new TopoStop() | 94 | + new TopoStop(), |
| 95 | + new ReqSummary() | ||
| 96 | + // TODO: add more handlers here..... | ||
| 78 | ); | 97 | ); |
| 79 | } | 98 | } |
| 80 | 99 | ||
| 81 | // ===================================================================== | 100 | // ===================================================================== |
| 101 | + // Overlay Service | ||
| 102 | + // TODO: figure out how we are going to switch overlays in and out... | ||
| 103 | + | ||
| 104 | + private final Map<String, SummaryGenerator> summGenCache = Maps.newHashMap(); | ||
| 105 | + | ||
| 106 | + @Override | ||
| 107 | + public void addSummaryGenerator(String overlayId, SummaryGenerator generator) { | ||
| 108 | + log.info("Adding custom Summary Generator for overlay [{}]", overlayId); | ||
| 109 | + summGenCache.put(overlayId, generator); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + @Override | ||
| 113 | + public void removeSummaryGenerator(String overlayId) { | ||
| 114 | + summGenCache.remove(overlayId); | ||
| 115 | + log.info("Custom Summary Generator for overlay [{}] removed", overlayId); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + | ||
| 119 | + | ||
| 120 | + // ===================================================================== | ||
| 82 | // Request Handlers for (topo view) events from the UI... | 121 | // Request Handlers for (topo view) events from the UI... |
| 83 | 122 | ||
| 84 | private final class TopoStart extends RequestHandler { | 123 | private final class TopoStart extends RequestHandler { |
| ... | @@ -91,7 +130,6 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -91,7 +130,6 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 91 | topoActive = true; | 130 | topoActive = true; |
| 92 | modelService.addListener(modelListener); | 131 | modelService.addListener(modelListener); |
| 93 | sendMessages(modelService.getInitialState()); | 132 | sendMessages(modelService.getInitialState()); |
| 94 | - log.debug(TOPO_START); | ||
| 95 | } | 133 | } |
| 96 | } | 134 | } |
| 97 | 135 | ||
| ... | @@ -104,7 +142,43 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -104,7 +142,43 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 104 | public void process(long sid, ObjectNode payload) { | 142 | public void process(long sid, ObjectNode payload) { |
| 105 | topoActive = false; | 143 | topoActive = false; |
| 106 | modelService.removeListener(modelListener); | 144 | modelService.removeListener(modelListener); |
| 107 | - log.debug(TOPO_STOP); | 145 | + } |
| 146 | + } | ||
| 147 | + | ||
| 148 | + private final class ReqSummary extends RequestHandler { | ||
| 149 | + private ReqSummary() { | ||
| 150 | + super(REQ_SUMMARY); | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + @Override | ||
| 154 | + public void process(long sid, ObjectNode payload) { | ||
| 155 | + modelService.startSummaryMonitoring(); | ||
| 156 | + // NOTE: showSummary messages forwarded through the model listener | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + // ===================================================================== | ||
| 161 | + | ||
| 162 | + private final class DefSummaryGenerator extends AbstractSummaryGenerator { | ||
| 163 | + public DefSummaryGenerator(String iconId, String title) { | ||
| 164 | + super(iconId, title); | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + @Override | ||
| 168 | + public ObjectNode generateSummary() { | ||
| 169 | + SummaryData data = modelService.getSummaryData(); | ||
| 170 | + iconId("node"); | ||
| 171 | + title("ONOS Summary"); | ||
| 172 | + clearProps(); | ||
| 173 | + prop("Devices", format(data.deviceCount())); | ||
| 174 | + prop("Links", format(data.linkCount())); | ||
| 175 | + prop("Hosts", format(data.hostCount())); | ||
| 176 | + prop("Topology SCCs", format(data.clusterCount())); | ||
| 177 | + separator(); | ||
| 178 | + prop("Intents", format(data.intentCount())); | ||
| 179 | + prop("Flows", format(data.flowRuleCount())); | ||
| 180 | + prop("Version", version); | ||
| 181 | + return buildObjectNode(); | ||
| 108 | } | 182 | } |
| 109 | } | 183 | } |
| 110 | 184 | ||
| ... | @@ -120,6 +194,15 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -120,6 +194,15 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 120 | } | 194 | } |
| 121 | } | 195 | } |
| 122 | 196 | ||
| 197 | + private void sendMessages(ObjectNode message) { | ||
| 198 | + if (topoActive) { | ||
| 199 | + UiConnection connection = connection(); | ||
| 200 | + if (connection != null) { | ||
| 201 | + connection.sendMessage(message); | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + | ||
| 123 | // ===================================================================== | 206 | // ===================================================================== |
| 124 | // Our listener for model events so we can push changes out to the UI... | 207 | // Our listener for model events so we can push changes out to the UI... |
| 125 | 208 | ||
| ... | @@ -127,7 +210,46 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { | ... | @@ -127,7 +210,46 @@ public class AltTopoViewMessageHandler extends UiMessageHandler { |
| 127 | @Override | 210 | @Override |
| 128 | public void event(TopoUiEvent event) { | 211 | public void event(TopoUiEvent event) { |
| 129 | log.debug("Handle Event: {}", event); | 212 | log.debug("Handle Event: {}", event); |
| 130 | - // TODO: handle event | 213 | + ModelEventHandler handler = eventHandlerBinding.get(event.type()); |
| 214 | + | ||
| 215 | + // any handlers not bound explicitly are assumed to be pass-thru... | ||
| 216 | + if (handler == null) { | ||
| 217 | + handler = passThruHandler; | ||
| 218 | + } | ||
| 219 | + handler.handleEvent(event); | ||
| 220 | + } | ||
| 131 | } | 221 | } |
| 222 | + | ||
| 223 | + | ||
| 224 | + // ===================================================================== | ||
| 225 | + // Model Event Handler definitions and bindings... | ||
| 226 | + | ||
| 227 | + private interface ModelEventHandler { | ||
| 228 | + void handleEvent(TopoUiEvent event); | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + private ModelEventHandler passThruHandler = event -> { | ||
| 232 | + // simply forward the event message as is | ||
| 233 | + ObjectNode message = event.subject(); | ||
| 234 | + if (message != null) { | ||
| 235 | + sendMessages(event.subject()); | ||
| 132 | } | 236 | } |
| 237 | + }; | ||
| 238 | + | ||
| 239 | + private ModelEventHandler summaryHandler = event -> { | ||
| 240 | + // use the currently selected summary generator to create the body.. | ||
| 241 | + ObjectNode payload = currentSummaryGenerator.generateSummary(); | ||
| 242 | + sendMessages(JsonUtils.envelope("showSummary", payload)); | ||
| 243 | + }; | ||
| 244 | + | ||
| 245 | + | ||
| 246 | + // TopoUiEvent type binding of handlers | ||
| 247 | + private final Map<TopoUiEvent.Type, ModelEventHandler> | ||
| 248 | + eventHandlerBinding = new HashMap<>(); | ||
| 249 | + | ||
| 250 | + private void bindEventHandlers() { | ||
| 251 | + eventHandlerBinding.put(SUMMARY_UPDATE, summaryHandler); | ||
| 252 | + // NOTE: no need to bind pass-thru handlers | ||
| 253 | + } | ||
| 254 | + | ||
| 133 | } | 255 | } | ... | ... |
| ... | @@ -194,6 +194,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -194,6 +194,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 194 | 194 | ||
| 195 | // ================================================================== | 195 | // ================================================================== |
| 196 | 196 | ||
| 197 | + @Deprecated | ||
| 197 | private final class TopoStart extends RequestHandler { | 198 | private final class TopoStart extends RequestHandler { |
| 198 | private TopoStart() { | 199 | private TopoStart() { |
| 199 | super(TOPO_START); | 200 | super(TOPO_START); |
| ... | @@ -209,6 +210,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -209,6 +210,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 209 | } | 210 | } |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 213 | + @Deprecated | ||
| 212 | private final class TopoStop extends RequestHandler { | 214 | private final class TopoStop extends RequestHandler { |
| 213 | private TopoStop() { | 215 | private TopoStop() { |
| 214 | super(TOPO_STOP); | 216 | super(TOPO_STOP); |
| ... | @@ -221,6 +223,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -221,6 +223,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 221 | } | 223 | } |
| 222 | } | 224 | } |
| 223 | 225 | ||
| 226 | + @Deprecated | ||
| 224 | private final class ReqSummary extends RequestHandler { | 227 | private final class ReqSummary extends RequestHandler { |
| 225 | private ReqSummary() { | 228 | private ReqSummary() { |
| 226 | super(REQ_SUMMARY); | 229 | super(REQ_SUMMARY); | ... | ... |
| ... | @@ -29,6 +29,8 @@ import org.onosproject.ui.UiExtensionService; | ... | @@ -29,6 +29,8 @@ import org.onosproject.ui.UiExtensionService; |
| 29 | import org.onosproject.ui.UiMessageHandlerFactory; | 29 | import org.onosproject.ui.UiMessageHandlerFactory; |
| 30 | import org.onosproject.ui.UiView; | 30 | import org.onosproject.ui.UiView; |
| 31 | import org.onosproject.ui.UiViewHidden; | 31 | import org.onosproject.ui.UiViewHidden; |
| 32 | +import org.onosproject.ui.impl.topo.OverlayService; | ||
| 33 | +import org.onosproject.ui.impl.topo.overlay.SummaryGenerator; | ||
| 32 | import org.slf4j.Logger; | 34 | import org.slf4j.Logger; |
| 33 | import org.slf4j.LoggerFactory; | 35 | import org.slf4j.LoggerFactory; |
| 34 | 36 | ||
| ... | @@ -46,7 +48,8 @@ import static org.onosproject.ui.UiView.Category.PLATFORM; | ... | @@ -46,7 +48,8 @@ import static org.onosproject.ui.UiView.Category.PLATFORM; |
| 46 | */ | 48 | */ |
| 47 | @Component(immediate = true) | 49 | @Component(immediate = true) |
| 48 | @Service | 50 | @Service |
| 49 | -public class UiExtensionManager implements UiExtensionService, SpriteService { | 51 | +public class UiExtensionManager |
| 52 | + implements UiExtensionService, SpriteService, OverlayService { | ||
| 50 | 53 | ||
| 51 | private final Logger log = LoggerFactory.getLogger(getClass()); | 54 | private final Logger log = LoggerFactory.getLogger(getClass()); |
| 52 | 55 | ||
| ... | @@ -59,9 +62,13 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -59,9 +62,13 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
| 59 | // Core views & core extension | 62 | // Core views & core extension |
| 60 | private final UiExtension core = createCoreExtension(); | 63 | private final UiExtension core = createCoreExtension(); |
| 61 | 64 | ||
| 65 | + // Topology Message Handler | ||
| 66 | + private final AltTopoViewMessageHandler topoHandler = | ||
| 67 | + new AltTopoViewMessageHandler(); | ||
| 68 | + | ||
| 62 | 69 | ||
| 63 | // Creates core UI extension | 70 | // Creates core UI extension |
| 64 | - private static UiExtension createCoreExtension() { | 71 | + private UiExtension createCoreExtension() { |
| 65 | List<UiView> coreViews = of( | 72 | List<UiView> coreViews = of( |
| 66 | new UiView(PLATFORM, "app", "Applications", "nav_apps"), | 73 | new UiView(PLATFORM, "app", "Applications", "nav_apps"), |
| 67 | new UiView(PLATFORM, "cluster", "Cluster Nodes", "nav_cluster"), | 74 | new UiView(PLATFORM, "cluster", "Cluster Nodes", "nav_cluster"), |
| ... | @@ -78,7 +85,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -78,7 +85,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
| 78 | UiMessageHandlerFactory messageHandlerFactory = | 85 | UiMessageHandlerFactory messageHandlerFactory = |
| 79 | () -> ImmutableList.of( | 86 | () -> ImmutableList.of( |
| 80 | new TopologyViewMessageHandler(), | 87 | new TopologyViewMessageHandler(), |
| 81 | -// new AltTopoViewMessageHandler(), | 88 | +// topoHandler, |
| 82 | new DeviceViewMessageHandler(), | 89 | new DeviceViewMessageHandler(), |
| 83 | new LinkViewMessageHandler(), | 90 | new LinkViewMessageHandler(), |
| 84 | new HostViewMessageHandler(), | 91 | new HostViewMessageHandler(), |
| ... | @@ -119,7 +126,8 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -119,7 +126,8 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
| 119 | @Override | 126 | @Override |
| 120 | public synchronized void unregister(UiExtension extension) { | 127 | public synchronized void unregister(UiExtension extension) { |
| 121 | extensions.remove(extension); | 128 | extensions.remove(extension); |
| 122 | - extension.views().stream().map(UiView::id).collect(toSet()).forEach(views::remove); | 129 | + extension.views().stream() |
| 130 | + .map(UiView::id).collect(toSet()).forEach(views::remove); | ||
| 123 | } | 131 | } |
| 124 | 132 | ||
| 125 | @Override | 133 | @Override |
| ... | @@ -132,9 +140,10 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -132,9 +140,10 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
| 132 | return views.get(viewId); | 140 | return views.get(viewId); |
| 133 | } | 141 | } |
| 134 | 142 | ||
| 135 | - | 143 | + // ===================================================================== |
| 136 | // Provisional tracking of sprite definitions | 144 | // Provisional tracking of sprite definitions |
| 137 | - private Map<String, JsonNode> sprites = Maps.newHashMap(); | 145 | + |
| 146 | + private final Map<String, JsonNode> sprites = Maps.newHashMap(); | ||
| 138 | 147 | ||
| 139 | @Override | 148 | @Override |
| 140 | public Set<String> getNames() { | 149 | public Set<String> getNames() { |
| ... | @@ -152,4 +161,18 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -152,4 +161,18 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
| 152 | return sprites.get(name); | 161 | return sprites.get(name); |
| 153 | } | 162 | } |
| 154 | 163 | ||
| 164 | + | ||
| 165 | + // ===================================================================== | ||
| 166 | + // Topology Overlay API -- pass through to topology message handler | ||
| 167 | + | ||
| 168 | + // NOTE: while WIP, comment out calls to topoHandler (for checked in code) | ||
| 169 | + @Override | ||
| 170 | + public void addSummaryGenerator(String overlayId, SummaryGenerator generator) { | ||
| 171 | + topoHandler.addSummaryGenerator(overlayId, generator); | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + @Override | ||
| 175 | + public void removeSummaryGenerator(String overlayId) { | ||
| 176 | + topoHandler.removeSummaryGenerator(overlayId); | ||
| 177 | + } | ||
| 155 | } | 178 | } | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 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 | + | ||
| 18 | +package org.onosproject.ui.impl.topo; | ||
| 19 | + | ||
| 20 | +import org.onosproject.ui.impl.topo.overlay.SummaryGenerator; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * Provides the API for external agents to inject topology overlay behavior. | ||
| 24 | + */ | ||
| 25 | +public interface OverlayService { | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * Registers a custom summary generator for the specified overlay. | ||
| 29 | + * | ||
| 30 | + * @param overlayId overlay identifier | ||
| 31 | + * @param generator generator to register | ||
| 32 | + */ | ||
| 33 | + void addSummaryGenerator(String overlayId, SummaryGenerator generator); | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * Unregisters the generator associated with the specified overlay. | ||
| 37 | + * | ||
| 38 | + * @param overlayId overlay identifier | ||
| 39 | + */ | ||
| 40 | + void removeSummaryGenerator(String overlayId); | ||
| 41 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 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 | + | ||
| 18 | +package org.onosproject.ui.impl.topo; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * Provides basic summary data for the topology. | ||
| 22 | + */ | ||
| 23 | +public interface SummaryData { | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * Returns the number of devices. | ||
| 27 | + * | ||
| 28 | + * @return number of devices | ||
| 29 | + */ | ||
| 30 | + int deviceCount(); | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * Returns the number of links. | ||
| 34 | + * | ||
| 35 | + * @return number of links | ||
| 36 | + */ | ||
| 37 | + int linkCount(); | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Returns the number of hosts. | ||
| 41 | + * | ||
| 42 | + * @return number of hosts | ||
| 43 | + */ | ||
| 44 | + int hostCount(); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Returns the number of clusters (topology SCCs). | ||
| 48 | + * | ||
| 49 | + * @return number of clusters | ||
| 50 | + */ | ||
| 51 | + int clusterCount(); | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * Returns the number of intents in the system. | ||
| 55 | + * | ||
| 56 | + * @return number of intents | ||
| 57 | + */ | ||
| 58 | + long intentCount(); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * Returns the number of flow rules in the system. | ||
| 62 | + * | ||
| 63 | + * @return number of flow rules | ||
| 64 | + */ | ||
| 65 | + int flowRuleCount(); | ||
| 66 | + | ||
| 67 | +} |
| ... | @@ -29,6 +29,10 @@ public class TopoUiEvent extends AbstractEvent<TopoUiEvent.Type, ObjectNode> { | ... | @@ -29,6 +29,10 @@ public class TopoUiEvent extends AbstractEvent<TopoUiEvent.Type, ObjectNode> { |
| 29 | * Type of Topology UI Model events. | 29 | * Type of Topology UI Model events. |
| 30 | */ | 30 | */ |
| 31 | public enum Type { | 31 | public enum Type { |
| 32 | + // notification events | ||
| 33 | + SUMMARY_UPDATE, | ||
| 34 | + | ||
| 35 | + // unsolicited topology events | ||
| 32 | INSTANCE_ADDED, | 36 | INSTANCE_ADDED, |
| 33 | INSTANCE_REMOVED, | 37 | INSTANCE_REMOVED, |
| 34 | DEVICE_ADDED, | 38 | DEVICE_ADDED, | ... | ... |
| ... | @@ -35,10 +35,14 @@ import org.onosproject.net.Host; | ... | @@ -35,10 +35,14 @@ import org.onosproject.net.Host; |
| 35 | import org.onosproject.net.Link; | 35 | import org.onosproject.net.Link; |
| 36 | import org.onosproject.net.device.DeviceEvent; | 36 | import org.onosproject.net.device.DeviceEvent; |
| 37 | import org.onosproject.net.device.DeviceService; | 37 | import org.onosproject.net.device.DeviceService; |
| 38 | +import org.onosproject.net.flow.FlowRuleService; | ||
| 38 | import org.onosproject.net.host.HostEvent; | 39 | import org.onosproject.net.host.HostEvent; |
| 39 | import org.onosproject.net.host.HostService; | 40 | import org.onosproject.net.host.HostService; |
| 41 | +import org.onosproject.net.intent.IntentService; | ||
| 40 | import org.onosproject.net.link.LinkEvent; | 42 | import org.onosproject.net.link.LinkEvent; |
| 41 | import org.onosproject.net.link.LinkService; | 43 | import org.onosproject.net.link.LinkService; |
| 44 | +import org.onosproject.net.topology.Topology; | ||
| 45 | +import org.onosproject.net.topology.TopologyService; | ||
| 42 | import org.slf4j.Logger; | 46 | import org.slf4j.Logger; |
| 43 | import org.slf4j.LoggerFactory; | 47 | import org.slf4j.LoggerFactory; |
| 44 | 48 | ||
| ... | @@ -51,6 +55,7 @@ import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED; | ... | @@ -51,6 +55,7 @@ import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED; |
| 51 | import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED; | 55 | import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED; |
| 52 | import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; | 56 | import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; |
| 53 | import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; | 57 | import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; |
| 58 | +import static org.onosproject.ui.impl.topo.TopoUiEvent.Type.SUMMARY_UPDATE; | ||
| 54 | 59 | ||
| 55 | 60 | ||
| 56 | /** | 61 | /** |
| ... | @@ -79,6 +84,14 @@ public class TopoUiModelManager implements TopoUiModelService { | ... | @@ -79,6 +84,14 @@ public class TopoUiModelManager implements TopoUiModelService { |
| 79 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 84 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 80 | protected MastershipService mastershipService; | 85 | protected MastershipService mastershipService; |
| 81 | 86 | ||
| 87 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 88 | + protected IntentService intentService; | ||
| 89 | + | ||
| 90 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 91 | + protected FlowRuleService flowRuleService; | ||
| 92 | + | ||
| 93 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 94 | + protected TopologyService topologyService; | ||
| 82 | 95 | ||
| 83 | 96 | ||
| 84 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 97 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| ... | @@ -103,6 +116,7 @@ public class TopoUiModelManager implements TopoUiModelService { | ... | @@ -103,6 +116,7 @@ public class TopoUiModelManager implements TopoUiModelService { |
| 103 | linkService, | 116 | linkService, |
| 104 | hostService, | 117 | hostService, |
| 105 | mastershipService | 118 | mastershipService |
| 119 | + // TODO: others?? | ||
| 106 | ); | 120 | ); |
| 107 | log.info("Started"); | 121 | log.info("Started"); |
| 108 | } | 122 | } |
| ... | @@ -113,6 +127,17 @@ public class TopoUiModelManager implements TopoUiModelService { | ... | @@ -113,6 +127,17 @@ public class TopoUiModelManager implements TopoUiModelService { |
| 113 | log.info("Stopped"); | 127 | log.info("Stopped"); |
| 114 | } | 128 | } |
| 115 | 129 | ||
| 130 | + | ||
| 131 | + // TODO: figure out how to cull zombie listeners | ||
| 132 | + // The problem is when one refreshes the GUI (topology view) | ||
| 133 | + // a new instance of AltTopoViewMessageHandler is created and added | ||
| 134 | + // as a listener, but we never got a TopoStop event, which is what | ||
| 135 | + // causes the listener (for an AltTopoViewMessageHandler instance) to | ||
| 136 | + // be removed. | ||
| 137 | + // ==== Somehow need to tie this in to the GUI-disconnected event. | ||
| 138 | + | ||
| 139 | + | ||
| 140 | + | ||
| 116 | @Override | 141 | @Override |
| 117 | public void addListener(TopoUiListener listener) { | 142 | public void addListener(TopoUiListener listener) { |
| 118 | listenerRegistry.addListener(listener); | 143 | listenerRegistry.addListener(listener); |
| ... | @@ -133,6 +158,60 @@ public class TopoUiModelManager implements TopoUiModelService { | ... | @@ -133,6 +158,60 @@ public class TopoUiModelManager implements TopoUiModelService { |
| 133 | return results; | 158 | return results; |
| 134 | } | 159 | } |
| 135 | 160 | ||
| 161 | + @Override | ||
| 162 | + public void startSummaryMonitoring() { | ||
| 163 | + // TODO: set up periodic monitoring task | ||
| 164 | + // send a summary now, and periodically... | ||
| 165 | + post(new TopoUiEvent(SUMMARY_UPDATE, null)); | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + @Override | ||
| 169 | + public void stopSummaryMonitoring() { | ||
| 170 | + // TODO: cancel monitoring task | ||
| 171 | + | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + @Override | ||
| 175 | + public SummaryData getSummaryData() { | ||
| 176 | + return new SummaryDataImpl(); | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + // ===================================================================== | ||
| 180 | + | ||
| 181 | + private final class SummaryDataImpl implements SummaryData { | ||
| 182 | + private final Topology topology = topologyService.currentTopology(); | ||
| 183 | + | ||
| 184 | + @Override | ||
| 185 | + public int deviceCount() { | ||
| 186 | + return topology.deviceCount(); | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + @Override | ||
| 190 | + public int linkCount() { | ||
| 191 | + return topology.linkCount(); | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + @Override | ||
| 195 | + public int hostCount() { | ||
| 196 | + return hostService.getHostCount(); | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + @Override | ||
| 200 | + public int clusterCount() { | ||
| 201 | + return topology.clusterCount(); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + @Override | ||
| 205 | + public long intentCount() { | ||
| 206 | + return intentService.getIntentCount(); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + @Override | ||
| 210 | + public int flowRuleCount() { | ||
| 211 | + return flowRuleService.getFlowRuleCount(); | ||
| 212 | + } | ||
| 213 | + } | ||
| 214 | + | ||
| 136 | // ===================================================================== | 215 | // ===================================================================== |
| 137 | 216 | ||
| 138 | private static final Comparator<? super ControllerNode> NODE_COMPARATOR = | 217 | private static final Comparator<? super ControllerNode> NODE_COMPARATOR = | ... | ... |
| ... | @@ -47,8 +47,27 @@ public interface TopoUiModelService { | ... | @@ -47,8 +47,27 @@ public interface TopoUiModelService { |
| 47 | * These will be in the form of "addInstance", "addDevice", "addLink", | 47 | * These will be in the form of "addInstance", "addDevice", "addLink", |
| 48 | * and "addHost" events, as appropriate. | 48 | * and "addHost" events, as appropriate. |
| 49 | * | 49 | * |
| 50 | - * @return initial state events | 50 | + * @return initial state messages |
| 51 | */ | 51 | */ |
| 52 | List<ObjectNode> getInitialState(); | 52 | List<ObjectNode> getInitialState(); |
| 53 | 53 | ||
| 54 | + /** | ||
| 55 | + * Starts the summary monitoring process. | ||
| 56 | + * <p> | ||
| 57 | + * Sends a "showSummary" message now, and schedules a task to send | ||
| 58 | + * updates whenever the data changes. | ||
| 59 | + */ | ||
| 60 | + void startSummaryMonitoring(); | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * Cancels the task that sends summary updates. | ||
| 64 | + */ | ||
| 65 | + void stopSummaryMonitoring(); | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Returns base data about the topology. | ||
| 69 | + * | ||
| 70 | + * @return summary data | ||
| 71 | + */ | ||
| 72 | + SummaryData getSummaryData(); | ||
| 54 | } | 73 | } | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 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 | + | ||
| 18 | +package org.onosproject.ui.impl.topo.overlay; | ||
| 19 | + | ||
| 20 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 21 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 22 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 23 | + | ||
| 24 | +import java.text.DecimalFormat; | ||
| 25 | +import java.util.ArrayList; | ||
| 26 | +import java.util.List; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * Base implementation of a {@link SummaryGenerator}. Provides convenience | ||
| 30 | + * methods for compiling a list of properties to be displayed in the summary | ||
| 31 | + * panel on the UI. | ||
| 32 | + */ | ||
| 33 | +public abstract class AbstractSummaryGenerator implements SummaryGenerator { | ||
| 34 | + private static final String NUMBER_FORMAT = "#,###"; | ||
| 35 | + private static final DecimalFormat DF = new DecimalFormat(NUMBER_FORMAT); | ||
| 36 | + private static final ObjectMapper MAPPER = new ObjectMapper(); | ||
| 37 | + | ||
| 38 | + private final List<Prop> props = new ArrayList<>(); | ||
| 39 | + private String iconId; | ||
| 40 | + private String title; | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * Constructs a summary generator without specifying the icon ID or title. | ||
| 44 | + * It is expected that the title (and optionally the icon ID) will be set | ||
| 45 | + * later via {@link #title(String)} (and {@link #iconId(String)}), before | ||
| 46 | + * {@link #buildObjectNode()} is invoked to generate the message payload. | ||
| 47 | + */ | ||
| 48 | + public AbstractSummaryGenerator() { | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Constructs a summary generator that uses the specified iconId ID and | ||
| 53 | + * title in its generated output. | ||
| 54 | + * | ||
| 55 | + * @param iconId iconId ID | ||
| 56 | + * @param title title | ||
| 57 | + */ | ||
| 58 | + public AbstractSummaryGenerator(String iconId, String title) { | ||
| 59 | + this.iconId = iconId; | ||
| 60 | + this.title = title; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * Subclasses need to provide an implementation. | ||
| 65 | + * | ||
| 66 | + * @return the summary payload | ||
| 67 | + */ | ||
| 68 | + @Override | ||
| 69 | + public abstract ObjectNode generateSummary(); | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Formats the given number into a string, using comma separator. | ||
| 73 | + * | ||
| 74 | + * @param number the number | ||
| 75 | + * @return formatted as a string | ||
| 76 | + */ | ||
| 77 | + protected String format(Number number) { | ||
| 78 | + return DF.format(number); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * Sets the iconId ID to use. | ||
| 83 | + * | ||
| 84 | + * @param iconId iconId ID | ||
| 85 | + */ | ||
| 86 | + protected void iconId(String iconId) { | ||
| 87 | + this.iconId = iconId; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + * Sets the summary panel title. | ||
| 92 | + * | ||
| 93 | + * @param title the title | ||
| 94 | + */ | ||
| 95 | + protected void title(String title) { | ||
| 96 | + this.title = title; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * Clears out the cache of properties. | ||
| 101 | + */ | ||
| 102 | + protected void clearProps() { | ||
| 103 | + props.clear(); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + /** | ||
| 107 | + * Adds a property to the summary. Note that the value is converted to | ||
| 108 | + * a string by invoking the <code>toString()</code> method on it. | ||
| 109 | + * | ||
| 110 | + * @param label the label | ||
| 111 | + * @param value the value | ||
| 112 | + */ | ||
| 113 | + protected void prop(String label, Object value) { | ||
| 114 | + props.add(new Prop(label, value)); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + /** | ||
| 118 | + * Adds a separator to the summary; when rendered on the client, a visible | ||
| 119 | + * break between properties. | ||
| 120 | + */ | ||
| 121 | + protected void separator() { | ||
| 122 | + props.add(new Prop("-", "")); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + * Builds an object node from the current state of the summary generator. | ||
| 127 | + * | ||
| 128 | + * @return summary payload as JSON object node | ||
| 129 | + */ | ||
| 130 | + protected ObjectNode buildObjectNode() { | ||
| 131 | + ObjectNode result = MAPPER.createObjectNode(); | ||
| 132 | + // NOTE: "id" and "type" are currently used for title and iconID | ||
| 133 | + // so that this structure can be "re-used" with detail panel payloads | ||
| 134 | + result.put("id", title).put("type", iconId); | ||
| 135 | + | ||
| 136 | + ObjectNode pnode = MAPPER.createObjectNode(); | ||
| 137 | + ArrayNode porder = MAPPER.createArrayNode(); | ||
| 138 | + | ||
| 139 | + for (Prop p : props) { | ||
| 140 | + porder.add(p.label); | ||
| 141 | + pnode.put(p.label, p.value); | ||
| 142 | + } | ||
| 143 | + result.set("propOrder", porder); | ||
| 144 | + result.set("props", pnode); | ||
| 145 | + | ||
| 146 | + return result; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + // =================================================================== | ||
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * Abstraction of a property, that is, a label-value pair. | ||
| 153 | + */ | ||
| 154 | + private static class Prop { | ||
| 155 | + private final String label; | ||
| 156 | + private final String value; | ||
| 157 | + | ||
| 158 | + public Prop(String label, Object value) { | ||
| 159 | + this.label = label; | ||
| 160 | + this.value = value.toString(); | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 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 | + | ||
| 18 | +package org.onosproject.ui.impl.topo.overlay; | ||
| 19 | + | ||
| 20 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * May be called upon to generate the summary messages for the topology view | ||
| 24 | + * in the GUI. | ||
| 25 | + * <p> | ||
| 26 | + * It is assumed that if a custom summary generator is installed on the server | ||
| 27 | + * (as part of a topology overlay), a peer custom summary message handler will | ||
| 28 | + * be installed on the client side to handle the messages thus generated. | ||
| 29 | + */ | ||
| 30 | +public interface SummaryGenerator { | ||
| 31 | + /** | ||
| 32 | + * Generates the payload for the "showSummary" message. | ||
| 33 | + * | ||
| 34 | + * @return the message payload | ||
| 35 | + */ | ||
| 36 | + ObjectNode generateSummary(); | ||
| 37 | +} |
-
Please register or login to post a comment