GUI -- Huge Refactoring of server-side message handlers (Part Two).
--- Well, it compiles, and seems to work, with the cursory testing I've done...
Change-Id: I0e59657c134e109850e4770766083370dfd9fdc2
diff --git a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java
index 1f31672..b3280c8 100644
--- a/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java
+++ b/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfUi.java
@@ -27,10 +27,11 @@
import org.apache.felix.scr.annotations.Service;
import org.onlab.osgi.ServiceDirectory;
import org.onosproject.intentperf.IntentPerfCollector.Sample;
+import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiExtension;
import org.onosproject.ui.UiExtensionService;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.UiView;
import java.util.Collection;
@@ -48,14 +49,20 @@
@Service(value = IntentPerfUi.class)
public class IntentPerfUi {
+ private static final String INTENT_PERF_START = "intentPerfStart";
+ private static final String INTENT_PERF_STOP = "intentPerfStop";
+
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected UiExtensionService uiExtensionService;
private final Set<StreamingControl> handlers = synchronizedSet(new HashSet<>());
- private List<UiView> views = ImmutableList.of(new UiView(OTHER, "intentPerf", "Intent Performance"));
- private UiExtension uiExtension = new UiExtension(views, this::newHandlers,
- getClass().getClassLoader());
+ private List<UiView> views = ImmutableList.of(
+ new UiView(OTHER, "intentPerf", "Intent Performance")
+ );
+
+ private UiExtension uiExtension =
+ new UiExtension(views, this::newHandlers, getClass().getClassLoader());
private IntentPerfCollector collector;
@@ -90,25 +97,22 @@
}
// Creates and returns session specific message handler.
- private Collection<UiMessageHandler> newHandlers() {
+ private Collection<UiMessageHandlerTwo> newHandlers() {
return ImmutableList.of(new StreamingControl());
}
+
// UI Message handlers for turning on/off reporting to a session.
- private class StreamingControl extends UiMessageHandler {
+ private class StreamingControl extends UiMessageHandlerTwo {
private boolean streamingEnabled = false;
- protected StreamingControl() {
- super(ImmutableSet.of("intentPerfStart", "intentPerfStop"));
- }
-
@Override
- public void process(ObjectNode message) {
- streamingEnabled = message.path("event").asText("unknown").equals("intentPerfStart");
- if (streamingEnabled) {
- sendInitData();
- }
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(
+ new IntentPerfStart(),
+ new IntentPerfStop()
+ );
}
@Override
@@ -129,17 +133,6 @@
}
}
- private void sendInitData() {
- ObjectNode rootNode = mapper.createObjectNode();
- ArrayNode an = mapper.createArrayNode();
- ArrayNode sn = mapper.createArrayNode();
- rootNode.set("headers", an);
- rootNode.set("samples", sn);
-
- collector.getSampleHeaders().forEach(an::add);
- collector.getSamples().forEach(s -> sn.add(sampleNode(s)));
- connection().sendMessage("intentPerfInit", 0, rootNode);
- }
private ObjectNode sampleNode(Sample sample) {
ObjectNode sampleNode = mapper.createObjectNode();
@@ -153,6 +146,47 @@
return sampleNode;
}
+ // ======================================================================
+
+ private final class IntentPerfStart extends RequestHandler {
+
+ private IntentPerfStart() {
+ super(INTENT_PERF_START);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ streamingEnabled = true;
+ sendInitData();
+ }
+
+ private void sendInitData() {
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ ArrayNode an = MAPPER.createArrayNode();
+ ArrayNode sn = MAPPER.createArrayNode();
+ rootNode.set("headers", an);
+ rootNode.set("samples", sn);
+
+ collector.getSampleHeaders().forEach(an::add);
+ collector.getSamples().forEach(s -> sn.add(sampleNode(s)));
+ sendMessage("intentPerfInit", 0, rootNode);
+ }
+ }
+
+ // ======================================================================
+
+ private final class IntentPerfStop extends RequestHandler {
+
+ private IntentPerfStop() {
+ super(INTENT_PERF_STOP);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ streamingEnabled = false;
+ }
+ }
+
}
}
diff --git a/core/api/src/main/java/org/onosproject/ui/JsonUtils.java b/core/api/src/main/java/org/onosproject/ui/JsonUtils.java
index 152fc9b..db753e2 100644
--- a/core/api/src/main/java/org/onosproject/ui/JsonUtils.java
+++ b/core/api/src/main/java/org/onosproject/ui/JsonUtils.java
@@ -61,6 +61,17 @@
}
/**
+ * Returns the sequence identifier from the specified event, or 0 (zero)
+ * if the "sid" property does not exist.
+ *
+ * @param event message event
+ * @return extracted sequence identifier
+ */
+ public static long sid(ObjectNode event) {
+ return number(event, "sid");
+ }
+
+ /**
* Returns the payload from the specified event.
*
* @param event message event
@@ -95,7 +106,7 @@
/**
* Returns the specified node property as a string, with a default fallback.
*
- * @param node message event
+ * @param node object node
* @param name property name
* @param defaultValue fallback value if property is absent
* @return property as a string
@@ -104,4 +115,15 @@
return node.path(name).asText(defaultValue);
}
+ /**
+ * Returns the specified node property as an object node.
+ *
+ * @param node object node
+ * @param name property name
+ * @return property as a node
+ */
+ public static ObjectNode node(ObjectNode node, String name) {
+ return (ObjectNode) node.path(name);
+ }
+
}
diff --git a/core/api/src/main/java/org/onosproject/ui/RequestHandler.java b/core/api/src/main/java/org/onosproject/ui/RequestHandler.java
new file mode 100644
index 0000000..7231dcf
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/ui/RequestHandler.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ui;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Abstraction of an entity that handles a specific request from the
+ * user interface client.
+ *
+ * @see UiMessageHandlerTwo
+ */
+public abstract class RequestHandler {
+
+ protected static final ObjectMapper MAPPER = new ObjectMapper();
+
+ private final String eventType;
+ private UiMessageHandlerTwo parent;
+
+
+ public RequestHandler(String eventType) {
+ this.eventType = eventType;
+ }
+
+ // package private
+ void setParent(UiMessageHandlerTwo parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Returns the event type that this handler handles.
+ *
+ * @return event type
+ */
+ public String eventType() {
+ return eventType;
+ }
+
+ /**
+ * Processes the incoming message payload from the client.
+ *
+ * @param sid message sequence identifier
+ * @param payload request message payload
+ */
+ public abstract void process(long sid, ObjectNode payload);
+
+
+
+ // ===================================================================
+ // === Convenience methods...
+
+ /**
+ * Returns implementation of the specified service class.
+ *
+ * @param serviceClass service class
+ * @param <T> type of service
+ * @return implementation class
+ * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found
+ */
+ protected <T> T get(Class<T> serviceClass) {
+ return parent.directory().get(serviceClass);
+ }
+
+ /**
+ * Sends a message back to the client.
+ *
+ * @param eventType message event type
+ * @param sid message sequence identifier
+ * @param payload message payload
+ */
+ protected void sendMessage(String eventType, long sid, ObjectNode payload) {
+ parent.connection().sendMessage(eventType, sid, payload);
+ }
+
+ /**
+ * Sends a message back to the client.
+ * Here, the message is preformatted; the assumption is it has its
+ * eventType, sid and payload attributes already filled in.
+ *
+ * @param message the message to send
+ */
+ protected void sendMessage(ObjectNode message) {
+ parent.connection().sendMessage(message);
+ }
+
+ /**
+ * Allows one request handler to pass the event on to another for
+ * further processing.
+ * Note that the message handlers must be defined in the same parent.
+ *
+ * @param eventType event type
+ * @param sid sequence identifier
+ * @param payload message payload
+ */
+ protected void chain(String eventType, long sid, ObjectNode payload) {
+ parent.exec(eventType, sid, payload);
+ }
+
+ // ===================================================================
+
+
+ // FIXME : Javadocs
+ protected String string(ObjectNode node, String key) {
+ return JsonUtils.string(node, key);
+ }
+
+ protected String string(ObjectNode node, String key, String defValue) {
+ return JsonUtils.string(node, key, defValue);
+ }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java b/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java
index 0482162..00b3595 100644
--- a/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java
+++ b/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java
@@ -40,6 +40,7 @@
* }
* </pre>
*/
+@Deprecated
public abstract class UiMessageHandler {
private final Set<String> messageTypes;
diff --git a/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java b/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java
index 522daa8..23bd5d4 100644
--- a/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java
+++ b/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerFactory.java
@@ -28,6 +28,6 @@
*
* @return collection of new handlers
*/
- Collection<UiMessageHandler> newHandlers();
+ Collection<UiMessageHandlerTwo> newHandlers();
}
diff --git a/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerTwo.java b/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerTwo.java
new file mode 100644
index 0000000..915bcaf
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/ui/UiMessageHandlerTwo.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ui;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.osgi.ServiceDirectory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Abstraction of an entity capable of processing a JSON message from the user
+ * interface client.
+ * <p>
+ * The message is a JSON object with the following structure:
+ * </p>
+ * <pre>
+ * {
+ * "type": "<em>event-type</em>",
+ * "sid": "<em>sequence-number</em>",
+ * "payload": {
+ * <em>arbitrary JSON object structure</em>
+ * }
+ * }
+ * </pre>
+ */
+public abstract class UiMessageHandlerTwo {
+
+ private final Map<String, RequestHandler> handlerMap = new HashMap<>();
+
+ private UiConnection connection;
+ private ServiceDirectory directory;
+
+ /**
+ * Mapper for creating ObjectNodes and ArrayNodes etc.
+ */
+ protected final ObjectMapper mapper = new ObjectMapper();
+
+ /**
+ * Binds the handlers returned from {@link #getHandlers()} to this
+ * instance.
+ */
+ void bindHandlers() {
+ Collection<RequestHandler> handlers = getHandlers();
+ checkNotNull(handlers, "Handlers cannot be null");
+ checkArgument(!handlers.isEmpty(), "Handlers cannot be empty");
+
+ for (RequestHandler h : handlers) {
+ h.setParent(this);
+ handlerMap.put(h.eventType(), h);
+ }
+ }
+
+ /**
+ * Subclasses must return the collection of handlers for the
+ * message types they handle.
+ *
+ * @return the message handler instances
+ */
+ protected abstract Collection<RequestHandler> getHandlers();
+
+ /**
+ * Returns the set of message types which this handler is capable of
+ * processing.
+ *
+ * @return set of message types
+ */
+ public Set<String> messageTypes() {
+ return Collections.unmodifiableSet(handlerMap.keySet());
+ }
+
+ /**
+ * Processes a JSON message from the user interface client.
+ *
+ * @param message JSON message
+ */
+ public void process(ObjectNode message) {
+ String type = JsonUtils.eventType(message);
+ long sid = JsonUtils.sid(message);
+ ObjectNode payload = JsonUtils.payload(message);
+ exec(type, sid, payload);
+ }
+
+ /**
+ * Finds the appropriate handler and executes the process method.
+ *
+ * @param eventType event type
+ * @param sid sequence identifier
+ * @param payload message payload
+ */
+ void exec(String eventType, long sid, ObjectNode payload) {
+ RequestHandler handler = handlerMap.get(eventType);
+ if (handler != null) {
+ handler.process(sid, payload);
+ }
+ }
+
+ /**
+ * Initializes the handler with the user interface connection and
+ * service directory context.
+ *
+ * @param connection user interface connection
+ * @param directory service directory
+ */
+ public void init(UiConnection connection, ServiceDirectory directory) {
+ this.connection = connection;
+ this.directory = directory;
+ bindHandlers();
+ }
+
+ /**
+ * Destroys the message handler context.
+ */
+ public void destroy() {
+ this.connection = null;
+ this.directory = null;
+ }
+
+ /**
+ * Returns the user interface connection with which this handler was primed.
+ *
+ * @return user interface connection
+ */
+ public UiConnection connection() {
+ return connection;
+ }
+
+ /**
+ * Returns the user interface connection with which this handler was primed.
+ *
+ * @return user interface connection
+ */
+ public ServiceDirectory directory() {
+ return directory;
+ }
+
+ /**
+ * Returns implementation of the specified service class.
+ *
+ * @param serviceClass service class
+ * @param <T> type of service
+ * @return implementation class
+ * @throws org.onlab.osgi.ServiceNotFoundException if no implementation found
+ */
+ protected <T> T get(Class<T> serviceClass) {
+ return directory.get(serviceClass);
+ }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/ui/table/AbstractTableRow.java b/core/api/src/main/java/org/onosproject/ui/table/AbstractTableRow.java
index 32a4396..5dd11a4 100644
--- a/core/api/src/main/java/org/onosproject/ui/table/AbstractTableRow.java
+++ b/core/api/src/main/java/org/onosproject/ui/table/AbstractTableRow.java
@@ -73,4 +73,19 @@
protected void add(String id, Object value) {
cells.put(id, value.toString());
}
+
+ /**
+ * Concatenates an arbitrary number of objects, using their
+ * toString() methods.
+ *
+ * @param items the items to concatenate
+ * @return a concatenated string
+ */
+ protected static String concat(Object... items) {
+ StringBuilder sb = new StringBuilder();
+ for (Object o : items) {
+ sb.append(o);
+ }
+ return sb.toString();
+ }
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
index 08408dc..2924c8b 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/ApplicationViewMessageHandler.java
@@ -22,13 +22,15 @@
import org.onosproject.app.ApplicationState;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
import org.onosproject.ui.table.TableRow;
import org.onosproject.ui.table.TableUtils;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@@ -37,62 +39,74 @@
/**
* Message handler for application view related messages.
*/
-public class ApplicationViewMessageHandler extends UiMessageHandler {
+public class ApplicationViewMessageHandler extends UiMessageHandlerTwo {
- /**
- * Creates a new message handler for the application messages.
- */
- protected ApplicationViewMessageHandler() {
- super(ImmutableSet.of("appDataRequest", "appManagementRequest"));
- }
+ private static final String APP_DATA_REQ = "appDataRequest";
+ private static final String APP_MGMT_REQ = "appManagementRequest";
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("appDataRequest")) {
- sendAppList(message);
- } else if (type.equals("appManagementRequest")) {
- processManagementCommand(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(
+ new AppDataRequest(),
+ new AppMgmtRequest()
+ );
+ }
+
+ // ======================================================================
+
+ private final class AppDataRequest extends RequestHandler {
+
+ private AppDataRequest() {
+ super(APP_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload);
+
+ ApplicationService service = get(ApplicationService.class);
+ TableRow[] rows = generateTableRows(service);
+ Arrays.sort(rows, rc);
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("apps", TableUtils.generateArrayNode(rows));
+
+ sendMessage("appDataResponse", 0, rootNode);
+ }
+
+ private TableRow[] generateTableRows(ApplicationService service) {
+ List<TableRow> list = service.getApplications().stream()
+ .map(application -> new ApplicationTableRow(service, application))
+ .collect(Collectors.toList());
+ return list.toArray(new TableRow[list.size()]);
}
}
+ // ======================================================================
- private void sendAppList(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload);
+ private final class AppMgmtRequest extends RequestHandler {
- ApplicationService service = get(ApplicationService.class);
- TableRow[] rows = generateTableRows(service);
- Arrays.sort(rows, rc);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("apps", TableUtils.generateArrayNode(rows));
+ private AppMgmtRequest() {
+ super(APP_MGMT_REQ);
+ }
- connection().sendMessage("appDataResponse", 0, rootNode);
- }
-
- private void processManagementCommand(ObjectNode message) {
- ObjectNode payload = payload(message);
- String action = string(payload, "action");
- String name = string(payload, "name");
- if (action != null && name != null) {
- ApplicationAdminService service = get(ApplicationAdminService.class);
- ApplicationId appId = service.getId(name);
- if (action.equals("activate")) {
- service.activate(appId);
- } else if (action.equals("deactivate")) {
- service.deactivate(appId);
- } else if (action.equals("uninstall")) {
- service.uninstall(appId);
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String action = string(payload, "action");
+ String name = string(payload, "name");
+ if (action != null && name != null) {
+ ApplicationAdminService service = get(ApplicationAdminService.class);
+ ApplicationId appId = service.getId(name);
+ if (action.equals("activate")) {
+ service.activate(appId);
+ } else if (action.equals("deactivate")) {
+ service.deactivate(appId);
+ } else if (action.equals("uninstall")) {
+ service.uninstall(appId);
+ }
+ chain(APP_DATA_REQ, sid, payload);
}
- sendAppList(message);
}
}
-
- private TableRow[] generateTableRows(ApplicationService service) {
- List<TableRow> list = service.getApplications().stream()
- .map(application -> new ApplicationTableRow(service, application))
- .collect(Collectors.toList());
- return list.toArray(new TableRow[list.size()]);
- }
+ // ======================================================================
/**
* TableRow implementation for
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/ClusterViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/ClusterViewMessageHandler.java
index 55592e3..ee2dcd5 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/ClusterViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/ClusterViewMessageHandler.java
@@ -23,57 +23,61 @@
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
import org.onosproject.ui.table.TableRow;
import org.onosproject.ui.table.TableUtils;
-import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
+import java.util.stream.Collectors;
/**
* Message handler for cluster view related messages.
*/
-public class ClusterViewMessageHandler extends UiMessageHandler {
+public class ClusterViewMessageHandler extends UiMessageHandlerTwo {
- /**
- * Creates a new message handler for the cluster messages.
- */
- protected ClusterViewMessageHandler() {
- super(ImmutableSet.of("clusterDataRequest"));
- }
+ private static final String CLUSTER_DATA_REQ = "clusterDataRequest";
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("clusterDataRequest")) {
- sendClusterList(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(new ClusterDataRequest());
+ }
+
+ // ======================================================================
+
+ private final class ClusterDataRequest extends RequestHandler {
+
+ private ClusterDataRequest() {
+ super(CLUSTER_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload);
+
+ ClusterService service = get(ClusterService.class);
+ TableRow[] rows = generateTableRows(service);
+ Arrays.sort(rows, rc);
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("clusters", TableUtils.generateArrayNode(rows));
+
+ sendMessage("clusterDataResponse", 0, rootNode);
+ }
+
+ private TableRow[] generateTableRows(ClusterService service) {
+ List<TableRow> list = service.getNodes().stream()
+ .map(node -> new ControllerNodeTableRow(service, node))
+ .collect(Collectors.toList());
+ return list.toArray(new TableRow[list.size()]);
}
}
- private void sendClusterList(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload);
-
- ClusterService service = get(ClusterService.class);
- TableRow[] rows = generateTableRows(service);
- Arrays.sort(rows, rc);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("clusters", TableUtils.generateArrayNode(rows));
-
- connection().sendMessage("clusterDataResponse", 0, rootNode);
- }
-
- private TableRow[] generateTableRows(ClusterService service) {
- List<TableRow> list = new ArrayList<>();
- for (ControllerNode node : service.getNodes()) {
- list.add(new ControllerNodeTableRow(service, node));
- }
- return list.toArray(new TableRow[list.size()]);
- }
+ // ======================================================================
/**
* TableRow implementation for {@link ControllerNode controller nodes}.
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
index 5015cb5..302863b 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
@@ -27,7 +27,8 @@
import org.onosproject.net.Port;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.LinkService;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
import org.onosproject.ui.table.TableRow;
@@ -35,6 +36,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -42,7 +44,10 @@
/**
* Message handler for device view related messages.
*/
-public class DeviceViewMessageHandler extends UiMessageHandler {
+public class DeviceViewMessageHandler extends UiMessageHandlerTwo {
+
+ private static final String DEV_DATA_REQ = "deviceDataRequest";
+ private static final String DEV_DETAIL_REQ = "deviceDetailRequest";
private static final String ID = "id";
private static final String TYPE = "type";
@@ -65,110 +70,120 @@
private static final String NAME = "name";
- /**
- * Creates a new message handler for the device messages.
- */
- protected DeviceViewMessageHandler() {
- super(ImmutableSet.of("deviceDataRequest", "deviceDetailsRequest"));
- }
-
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("deviceDataRequest")) {
- dataRequest(message);
- } else if (type.equals("deviceDetailsRequest")) {
- detailsRequest(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(
+ new DataRequestHandler(),
+ new DetailRequestHandler()
+ );
+ }
+
+ // ======================================================================
+
+ private final class DataRequestHandler extends RequestHandler {
+
+ private DataRequestHandler() {
+ super(DEV_DATA_REQ);
}
- }
- private void dataRequest(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload);
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload);
- DeviceService service = get(DeviceService.class);
- MastershipService mastershipService = get(MastershipService.class);
- TableRow[] rows = generateTableRows(service, mastershipService);
- Arrays.sort(rows, rc);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("devices", TableUtils.generateArrayNode(rows));
+ DeviceService service = get(DeviceService.class);
+ MastershipService mastershipService = get(MastershipService.class);
+ TableRow[] rows = generateTableRows(service, mastershipService);
+ Arrays.sort(rows, rc);
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("devices", TableUtils.generateArrayNode(rows));
- connection().sendMessage("deviceDataResponse", 0, rootNode);
- }
-
- private void detailsRequest(ObjectNode message) {
- ObjectNode payload = payload(message);
- String id = string(payload, "id", "of:0000000000000000");
-
- DeviceId deviceId = DeviceId.deviceId(id);
- DeviceService service = get(DeviceService.class);
- MastershipService ms = get(MastershipService.class);
- Device device = service.getDevice(deviceId);
- ObjectNode data = mapper.createObjectNode();
-
- data.put(ID, deviceId.toString());
- data.put(TYPE, device.type().toString());
- data.put(TYPE_IID, getTypeIconId(device));
- data.put(MFR, device.manufacturer());
- data.put(HW, device.hwVersion());
- data.put(SW, device.swVersion());
- data.put(SERIAL, device.serialNumber());
- data.put(CHASSIS_ID, device.chassisId().toString());
- data.put(MASTER_ID, ms.getMasterFor(deviceId).toString());
- data.put(PROTOCOL, device.annotations().value(PROTOCOL));
-
- ArrayNode ports = mapper.createArrayNode();
-
- List<Port> portList = new ArrayList<>(service.getPorts(deviceId));
- Collections.sort(portList, (p1, p2) -> {
- long delta = p1.number().toLong() - p2.number().toLong();
- return delta == 0 ? 0 : (delta < 0 ? -1 : +1);
- });
-
- for (Port p : portList) {
- ports.add(portData(p, deviceId));
+ sendMessage("deviceDataResponse", 0, rootNode);
}
- data.set(PORTS, ports);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("details", data);
- connection().sendMessage("deviceDetailsResponse", 0, rootNode);
- }
-
- private TableRow[] generateTableRows(DeviceService service,
- MastershipService mastershipService) {
- List<TableRow> list = new ArrayList<>();
- for (Device dev : service.getDevices()) {
- list.add(new DeviceTableRow(service, mastershipService, dev));
- }
- return list.toArray(new TableRow[list.size()]);
- }
-
- private ObjectNode portData(Port p, DeviceId id) {
- ObjectNode port = mapper.createObjectNode();
- LinkService ls = get(LinkService.class);
- String name = p.annotations().value(AnnotationKeys.PORT_NAME);
-
- port.put(ID, p.number().toString());
- port.put(TYPE, p.type().toString());
- port.put(SPEED, p.portSpeed());
- port.put(ENABLED, p.isEnabled());
- port.put(NAME, name != null ? name : "");
-
- Set<Link> links = ls.getEgressLinks(new ConnectPoint(id, p.number()));
- if (!links.isEmpty()) {
- StringBuilder egressLinks = new StringBuilder();
- for (Link l : links) {
- ConnectPoint dest = l.dst();
- egressLinks.append(dest.elementId()).append("/")
- .append(dest.port()).append(" ");
+ private TableRow[] generateTableRows(DeviceService service,
+ MastershipService mastershipService) {
+ List<TableRow> list = new ArrayList<>();
+ for (Device dev : service.getDevices()) {
+ list.add(new DeviceTableRow(service, mastershipService, dev));
}
- port.put(LINK_DEST, egressLinks.toString());
+ return list.toArray(new TableRow[list.size()]);
+ }
+ }
+
+ // ======================================================================
+
+ private final class DetailRequestHandler extends RequestHandler {
+ private DetailRequestHandler() {
+ super(DEV_DETAIL_REQ);
}
- return port;
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String id = string(payload, "id", "of:0000000000000000");
+
+ DeviceId deviceId = DeviceId.deviceId(id);
+ DeviceService service = get(DeviceService.class);
+ MastershipService ms = get(MastershipService.class);
+ Device device = service.getDevice(deviceId);
+ ObjectNode data = MAPPER.createObjectNode();
+
+ data.put(ID, deviceId.toString());
+ data.put(TYPE, device.type().toString());
+ data.put(TYPE_IID, getTypeIconId(device));
+ data.put(MFR, device.manufacturer());
+ data.put(HW, device.hwVersion());
+ data.put(SW, device.swVersion());
+ data.put(SERIAL, device.serialNumber());
+ data.put(CHASSIS_ID, device.chassisId().toString());
+ data.put(MASTER_ID, ms.getMasterFor(deviceId).toString());
+ data.put(PROTOCOL, device.annotations().value(PROTOCOL));
+
+ ArrayNode ports = MAPPER.createArrayNode();
+
+ List<Port> portList = new ArrayList<>(service.getPorts(deviceId));
+ Collections.sort(portList, (p1, p2) -> {
+ long delta = p1.number().toLong() - p2.number().toLong();
+ return delta == 0 ? 0 : (delta < 0 ? -1 : +1);
+ });
+
+ for (Port p : portList) {
+ ports.add(portData(p, deviceId));
+ }
+ data.set(PORTS, ports);
+
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("details", data);
+ sendMessage("deviceDetailsResponse", 0, rootNode);
+ }
+
+ private ObjectNode portData(Port p, DeviceId id) {
+ ObjectNode port = MAPPER.createObjectNode();
+ LinkService ls = get(LinkService.class);
+ String name = p.annotations().value(AnnotationKeys.PORT_NAME);
+
+ port.put(ID, p.number().toString());
+ port.put(TYPE, p.type().toString());
+ port.put(SPEED, p.portSpeed());
+ port.put(ENABLED, p.isEnabled());
+ port.put(NAME, name != null ? name : "");
+
+ Set<Link> links = ls.getEgressLinks(new ConnectPoint(id, p.number()));
+ if (!links.isEmpty()) {
+ StringBuilder egressLinks = new StringBuilder();
+ for (Link l : links) {
+ ConnectPoint dest = l.dst();
+ egressLinks.append(dest.elementId()).append("/")
+ .append(dest.port()).append(" ");
+ }
+ port.put(LINK_DEST, egressLinks.toString());
+ }
+
+ return port;
+ }
+
}
+
private static String getTypeIconId(Device d) {
return DEV_ICON_PREFIX + d.type().toString();
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
index 81965da..0ad1d70 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/FlowViewMessageHandler.java
@@ -26,7 +26,8 @@
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
import org.onosproject.ui.table.TableRow;
@@ -34,6 +35,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -41,54 +43,57 @@
/**
* Message handler for flow view related messages.
*/
-public class FlowViewMessageHandler extends UiMessageHandler {
+public class FlowViewMessageHandler extends UiMessageHandlerTwo {
+
+ private static final String FLOW_DATA_REQ = "flowDataRequest";
private static final String NO_DEV = "none";
- /**
- * Creates a new message handler for the flow messages.
- */
- protected FlowViewMessageHandler() {
- super(ImmutableSet.of("flowDataRequest"));
- }
-
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("flowDataRequest")) {
- sendFlowList(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(new FlowDataRequest());
+ }
+
+ // ======================================================================
+
+ private final class FlowDataRequest extends RequestHandler {
+
+ private FlowDataRequest() {
+ super(FLOW_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload);
+ String uri = string(payload, "devId", NO_DEV);
+
+ ObjectNode rootNode;
+ if (uri.equals(NO_DEV)) {
+ rootNode = MAPPER.createObjectNode();
+ rootNode.set("flows", MAPPER.createArrayNode());
+ } else {
+ DeviceId deviceId = DeviceId.deviceId(uri);
+ FlowRuleService service = get(FlowRuleService.class);
+ TableRow[] rows = generateTableRows(service, deviceId);
+ Arrays.sort(rows, rc);
+ rootNode = MAPPER.createObjectNode();
+ rootNode.set("flows", TableUtils.generateArrayNode(rows));
+ }
+
+ sendMessage("flowDataResponse", 0, rootNode);
+ }
+
+ private TableRow[] generateTableRows(FlowRuleService service,
+ DeviceId deviceId) {
+ List<TableRow> list = new ArrayList<>();
+ for (FlowEntry flow : service.getFlowEntries(deviceId)) {
+ list.add(new FlowTableRow(flow));
+ }
+ return list.toArray(new TableRow[list.size()]);
}
}
- private void sendFlowList(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload);
- String uri = string(payload, "devId", NO_DEV);
-
- ObjectNode rootNode;
- if (uri.equals(NO_DEV)) {
- rootNode = mapper.createObjectNode();
- rootNode.set("flows", mapper.createArrayNode());
- } else {
- DeviceId deviceId = DeviceId.deviceId(uri);
- FlowRuleService service = get(FlowRuleService.class);
- TableRow[] rows = generateTableRows(service, deviceId);
- Arrays.sort(rows, rc);
- rootNode = mapper.createObjectNode();
- rootNode.set("flows", TableUtils.generateArrayNode(rows));
- }
-
- connection().sendMessage("flowDataResponse", 0, rootNode);
- }
-
- private TableRow[] generateTableRows(FlowRuleService service,
- DeviceId deviceId) {
- List<TableRow> list = new ArrayList<>();
- for (FlowEntry flow : service.getFlowEntries(deviceId)) {
- list.add(new FlowTableRow(flow));
- }
- return list.toArray(new TableRow[list.size()]);
- }
+ // ======================================================================
/**
* TableRow implementation for {@link org.onosproject.net.flow.FlowRule flows}.
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java
index 472ae16..a4127e0 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/HostViewMessageHandler.java
@@ -21,7 +21,8 @@
import org.onosproject.net.Host;
import org.onosproject.net.HostLocation;
import org.onosproject.net.host.HostService;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
import org.onosproject.ui.table.TableRow;
@@ -29,6 +30,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -36,43 +38,47 @@
/**
* Message handler for host view related messages.
*/
-public class HostViewMessageHandler extends UiMessageHandler {
+public class HostViewMessageHandler extends UiMessageHandlerTwo {
- /**
- * Creates a new message handler for the host messages.
- */
- protected HostViewMessageHandler() {
- super(ImmutableSet.of("hostDataRequest"));
- }
+ private static final String HOST_DATA_REQ = "hostDataRequest";
+
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("hostDataRequest")) {
- sendHostList(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(new HostDataRequest());
+ }
+
+ // ======================================================================
+
+ private final class HostDataRequest extends RequestHandler {
+
+ private HostDataRequest() {
+ super(HOST_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload);
+
+ HostService service = get(HostService.class);
+ TableRow[] rows = generateTableRows(service);
+ Arrays.sort(rows, rc);
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("hosts", TableUtils.generateArrayNode(rows));
+
+ sendMessage("hostDataResponse", 0, rootNode);
+ }
+
+ private TableRow[] generateTableRows(HostService service) {
+ List<TableRow> list = new ArrayList<>();
+ for (Host host : service.getHosts()) {
+ list.add(new HostTableRow(host));
+ }
+ return list.toArray(new TableRow[list.size()]);
}
}
- private void sendHostList(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload);
-
- HostService service = get(HostService.class);
- TableRow[] rows = generateTableRows(service);
- Arrays.sort(rows, rc);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("hosts", TableUtils.generateArrayNode(rows));
-
- connection().sendMessage("hostDataResponse", 0, rootNode);
- }
-
- private TableRow[] generateTableRows(HostService service) {
- List<TableRow> list = new ArrayList<>();
- for (Host host : service.getHosts()) {
- list.add(new HostTableRow(host));
- }
- return list.toArray(new TableRow[list.size()]);
- }
+ // ======================================================================
/**
* TableRow implementation for {@link Host hosts}.
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java
index 4924d4b..539430a 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/IntentViewMessageHandler.java
@@ -31,7 +31,8 @@
import org.onosproject.net.intent.PathIntent;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.net.intent.SinglePointToMultiPointIntent;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
import org.onosproject.ui.table.TableRow;
@@ -39,49 +40,54 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* Message handler for intent view related messages.
*/
-public class IntentViewMessageHandler extends UiMessageHandler {
+public class IntentViewMessageHandler extends UiMessageHandlerTwo {
- /**
- * Creates a new message handler for the intent messages.
- */
- protected IntentViewMessageHandler() {
- super(ImmutableSet.of("intentDataRequest"));
- }
+ private static final String INTENT_DATA_REQ = "intentDataRequest";
+
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("intentDataRequest")) {
- sendIntentList(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(new IntentDataRequest());
+ }
+
+ // ======================================================================
+
+ private final class IntentDataRequest extends RequestHandler {
+
+ private IntentDataRequest() {
+ super(INTENT_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload);
+
+ IntentService service = get(IntentService.class);
+ TableRow[] rows = generateTableRows(service);
+ Arrays.sort(rows, rc);
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("intents", TableUtils.generateArrayNode(rows));
+
+ sendMessage("intentDataResponse", 0, rootNode);
+ }
+
+ private TableRow[] generateTableRows(IntentService service) {
+ List<TableRow> list = new ArrayList<>();
+ for (Intent intent : service.getIntents()) {
+ list.add(new IntentTableRow(intent));
+ }
+ return list.toArray(new TableRow[list.size()]);
}
}
- private void sendIntentList(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload);
-
- IntentService service = get(IntentService.class);
- TableRow[] rows = generateTableRows(service);
- Arrays.sort(rows, rc);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("intents", TableUtils.generateArrayNode(rows));
-
- connection().sendMessage("intentDataResponse", 0, rootNode);
- }
-
- private TableRow[] generateTableRows(IntentService service) {
- List<TableRow> list = new ArrayList<>();
- for (Intent intent : service.getIntents()) {
- list.add(new IntentTableRow(intent));
- }
- return list.toArray(new TableRow[list.size()]);
- }
+ // ======================================================================
/**
* TableRow implementation for {@link Intent intents}.
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java
index 6683188..55291c4 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/LinkViewMessageHandler.java
@@ -23,7 +23,8 @@
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.link.LinkService;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.onosproject.ui.impl.TopologyViewMessageHandlerBase.BiLink;
import org.onosproject.ui.table.AbstractTableRow;
import org.onosproject.ui.table.RowComparator;
@@ -32,6 +33,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -40,47 +42,51 @@
/**
* Message handler for link view related messages.
*/
-public class LinkViewMessageHandler extends UiMessageHandler {
+public class LinkViewMessageHandler extends UiMessageHandlerTwo {
- /**
- * Creates a new message handler for the link messages.
- */
- protected LinkViewMessageHandler() {
- super(ImmutableSet.of("linkDataRequest"));
- }
+ private static final String LINK_DATA_REQ = "linkDataRequest";
+
@Override
- public void process(ObjectNode message) {
- String type = eventType(message);
- if (type.equals("linkDataRequest")) {
- sendLinkList(message);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(new LinkDataRequest());
+ }
+
+ // ======================================================================
+
+ private final class LinkDataRequest extends RequestHandler {
+
+ private LinkDataRequest() {
+ super(LINK_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ RowComparator rc = TableUtils.createRowComparator(payload, "one");
+
+ LinkService service = get(LinkService.class);
+ TableRow[] rows = generateTableRows(service);
+ Arrays.sort(rows, rc);
+ ObjectNode rootNode = MAPPER.createObjectNode();
+ rootNode.set("links", TableUtils.generateArrayNode(rows));
+
+ sendMessage("linkDataResponse", 0, rootNode);
+ }
+
+ private TableRow[] generateTableRows(LinkService service) {
+ List<TableRow> list = new ArrayList<>();
+
+ // First consolidate all uni-directional links into two-directional ones.
+ Map<LinkKey, BiLink> biLinks = Maps.newHashMap();
+ service.getLinks().forEach(link -> addLink(biLinks, link));
+
+ // Now scan over all bi-links and produce table rows from them.
+ biLinks.values().forEach(biLink -> list.add(new LinkTableRow(biLink)));
+ return list.toArray(new TableRow[list.size()]);
}
}
- private void sendLinkList(ObjectNode message) {
- ObjectNode payload = payload(message);
- RowComparator rc = TableUtils.createRowComparator(payload, "one");
-
- LinkService service = get(LinkService.class);
- TableRow[] rows = generateTableRows(service);
- Arrays.sort(rows, rc);
- ObjectNode rootNode = mapper.createObjectNode();
- rootNode.set("links", TableUtils.generateArrayNode(rows));
-
- connection().sendMessage("linkDataResponse", 0, rootNode);
- }
-
- private TableRow[] generateTableRows(LinkService service) {
- List<TableRow> list = new ArrayList<>();
-
- // First consolidate all uni-directional links into two-directional ones.
- Map<LinkKey, BiLink> biLinks = Maps.newHashMap();
- service.getLinks().forEach(link -> addLink(biLinks, link));
-
- // Now scan over all bi-links and produce table rows from them.
- biLinks.values().forEach(biLink -> list.add(new LinkTableRow(biLink)));
- return list.toArray(new TableRow[list.size()]);
- }
+ // ======================================================================
/**
* TableRow implementation for {@link org.onosproject.net.Link links}.
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
index 8ba8d3a..9e0339e 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -54,9 +54,12 @@
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
+import org.onosproject.ui.JsonUtils;
+import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@@ -79,6 +82,26 @@
*/
public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
+ private static final String REQ_DETAILS = "requestDetails";
+ private static final String UPDATE_META = "updateMeta";
+ private static final String ADD_HOST_INTENT = "addHostIntent";
+ private static final String ADD_MULTI_SRC_INTENT = "addMultiSourceIntent";
+ private static final String REQ_RELATED_INTENTS = "requestRelatedIntents";
+ private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent";
+ private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent";
+ private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic";
+ private static final String REQ_ALL_TRAFFIC = "requestAllTraffic";
+ private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows";
+ private static final String CANCEL_TRAFFIC = "cancelTraffic";
+ private static final String REQ_SUMMARY = "requestSummary";
+ private static final String CANCEL_SUMMARY = "cancelSummary";
+ private static final String EQ_MASTERS = "equalizeMasters";
+ private static final String SPRITE_LIST_REQ = "spriteListRequest";
+ private static final String SPRITE_DATA_REQ = "spriteDataRequest";
+ private static final String TOPO_START = "topoStart";
+ private static final String TOPO_STOP = "topoStop";
+
+
private static final String APP_ID = "org.onosproject.gui";
private static final long TRAFFIC_FREQUENCY = 5000;
@@ -111,11 +134,11 @@
private final Accumulator<Event> eventAccummulator = new InternalEventAccummulator();
- private TimerTask trafficTask;
- private ObjectNode trafficEvent;
+ private TimerTask trafficTask = null;
+ private TrafficEvent trafficEvent = null;
- private TimerTask summaryTask;
- private ObjectNode summaryEvent;
+ private TimerTask summaryTask = null;
+ private boolean summaryRunning = false;
private boolean listenersRemoved = false;
@@ -127,30 +150,6 @@
private List<Intent> selectedIntents;
private int currentIntentIndex = -1;
- /**
- * Creates a new web-socket for serving data to GUI topology view.
- */
- public TopologyViewMessageHandler() {
- super(ImmutableSet.of("topoStart",
- "topoStop",
- "requestDetails",
- "updateMeta",
- "addHostIntent",
- "addMultiSourceIntent",
- "requestRelatedIntents",
- "requestNextRelatedIntent",
- "requestPrevRelatedIntent",
- "requestSelectedIntentTraffic",
- "requestAllTraffic",
- "requestDeviceLinkFlows",
- "cancelTraffic",
- "requestSummary",
- "cancelSummary",
- "equalizeMasters",
- "spriteListRequest",
- "spriteDataRequest"
- ));
- }
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
@@ -167,66 +166,326 @@
super.destroy();
}
- // Processes the specified event.
@Override
- public void process(ObjectNode event) {
- String type = string(event, "event", "unknown");
- if (type.equals("requestDetails")) {
- requestDetails(event);
- } else if (type.equals("updateMeta")) {
- updateMetaUi(event);
+ protected Collection<RequestHandler> getHandlers() {
+ return ImmutableSet.of(
+ new TopoStart(),
+ new TopoStop(),
+ new ReqSummary(),
+ new CancelSummary(),
+ new SpriteListReq(),
+ new SpriteDataReq(),
+ new RequestDetails(),
+ new UpdateMeta(),
+ new EqMasters(),
- } else if (type.equals("addHostIntent")) {
- createHostIntent(event);
- } else if (type.equals("addMultiSourceIntent")) {
- createMultiSourceIntent(event);
+ // TODO: migrate traffic related to separate app
+ new AddHostIntent(),
+ new AddMultiSourceIntent(),
+ new ReqRelatedIntents(),
+ new ReqNextIntent(),
+ new ReqPrevIntent(),
+ new ReqSelectedIntentTraffic(),
+ new ReqAllTraffic(),
+ new ReqDevLinkFlows(),
+ new CancelTraffic()
+ );
+ }
- } else if (type.equals("requestRelatedIntents")) {
- stopTrafficMonitoring();
- requestRelatedIntents(event);
+ // ==================================================================
- } else if (type.equals("requestNextRelatedIntent")) {
- stopTrafficMonitoring();
- requestAnotherRelatedIntent(event, +1);
- } else if (type.equals("requestPrevRelatedIntent")) {
- stopTrafficMonitoring();
- requestAnotherRelatedIntent(event, -1);
- } else if (type.equals("requestSelectedIntentTraffic")) {
- requestSelectedIntentTraffic(event);
- startTrafficMonitoring(event);
+ private final class TopoStart extends RequestHandler {
+ private TopoStart() {
+ super(TOPO_START);
+ }
- } else if (type.equals("requestAllTraffic")) {
- requestAllTraffic(event);
- startTrafficMonitoring(event);
-
- } else if (type.equals("requestDeviceLinkFlows")) {
- requestDeviceLinkFlows(event);
- startTrafficMonitoring(event);
-
- } else if (type.equals("cancelTraffic")) {
- cancelTraffic(event);
-
- } else if (type.equals("requestSummary")) {
- requestSummary(event);
- startSummaryMonitoring(event);
- } else if (type.equals("cancelSummary")) {
- stopSummaryMonitoring();
-
- } else if (type.equals("equalizeMasters")) {
- equalizeMasters(event);
-
- } else if (type.equals("spriteListRequest")) {
- sendSpriteList(event);
- } else if (type.equals("spriteDataRequest")) {
- sendSpriteData(event);
-
- } else if (type.equals("topoStart")) {
- sendAllInitialData();
- } else if (type.equals("topoStop")) {
- cancelAllRequests();
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ addListeners();
+ sendAllInstances(null);
+ sendAllDevices();
+ sendAllLinks();
+ sendAllHosts();
}
}
+ private final class TopoStop extends RequestHandler {
+ private TopoStop() {
+ super(TOPO_STOP);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ stopSummaryMonitoring();
+ stopTrafficMonitoring();
+ }
+ }
+
+ private final class ReqSummary extends RequestHandler {
+ private ReqSummary() {
+ super(REQ_SUMMARY);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ requestSummary(sid);
+ startSummaryMonitoring();
+ }
+ }
+
+ private final class CancelSummary extends RequestHandler {
+ private CancelSummary() {
+ super(CANCEL_SUMMARY);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ stopSummaryMonitoring();
+ }
+ }
+
+ private final class SpriteListReq extends RequestHandler {
+ private SpriteListReq() {
+ super(SPRITE_LIST_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ ObjectNode root = mapper.createObjectNode();
+ ArrayNode names = mapper.createArrayNode();
+ get(SpriteService.class).getNames().forEach(names::add);
+ root.set("names", names);
+ sendMessage("spriteListResponse", sid, root);
+ }
+ }
+
+ private final class SpriteDataReq extends RequestHandler {
+ private SpriteDataReq() {
+ super(SPRITE_DATA_REQ);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String name = string(payload, "name");
+ ObjectNode root = mapper.createObjectNode();
+ root.set("data", get(SpriteService.class).get(name));
+ sendMessage("spriteDataResponse", sid, root);
+ }
+ }
+
+ private final class RequestDetails extends RequestHandler {
+ private RequestDetails() {
+ super(REQ_DETAILS);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ String type = string(payload, "class", "unknown");
+ String id = JsonUtils.string(payload, "id");
+
+ if (type.equals("device")) {
+ sendMessage(deviceDetails(deviceId(id), sid));
+ } else if (type.equals("host")) {
+ sendMessage(hostDetails(hostId(id), sid));
+ }
+ }
+ }
+
+ private final class UpdateMeta extends RequestHandler {
+ private UpdateMeta() {
+ super(UPDATE_META);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ updateMetaUi(payload);
+ }
+ }
+
+ private final class EqMasters extends RequestHandler {
+ private EqMasters() {
+ super(EQ_MASTERS);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ directory.get(MastershipAdminService.class).balanceRoles();
+ }
+ }
+
+ // === TODO: move traffic related classes to traffic app
+
+ private final class AddHostIntent extends RequestHandler {
+ private AddHostIntent() {
+ super(ADD_HOST_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ // TODO: add protection against device ids and non-existent hosts.
+ HostId one = hostId(string(payload, "one"));
+ HostId two = hostId(string(payload, "two"));
+
+ HostToHostIntent intent = HostToHostIntent.builder()
+ .appId(appId)
+ .one(one)
+ .two(two)
+ .build();
+
+ intentService.submit(intent);
+ startMonitoringIntent(intent);
+ }
+ }
+
+ private final class AddMultiSourceIntent extends RequestHandler {
+ private AddMultiSourceIntent() {
+ super(ADD_MULTI_SRC_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ // TODO: add protection against device ids and non-existent hosts.
+ Set<HostId> src = getHostIds((ArrayNode) payload.path("src"));
+ HostId dst = hostId(string(payload, "dst"));
+ Host dstHost = hostService.getHost(dst);
+
+ Set<ConnectPoint> ingressPoints = getHostLocations(src);
+
+ // FIXME: clearly, this is not enough
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthDst(dstHost.mac()).build();
+ TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+ MultiPointToSinglePointIntent intent =
+ MultiPointToSinglePointIntent.builder()
+ .appId(appId)
+ .selector(selector)
+ .treatment(treatment)
+ .ingressPoints(ingressPoints)
+ .egressPoint(dstHost.location())
+ .build();
+
+ intentService.submit(intent);
+ startMonitoringIntent(intent);
+ }
+ }
+
+ private final class ReqRelatedIntents extends RequestHandler {
+ private ReqRelatedIntents() {
+ super(REQ_RELATED_INTENTS);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ // Cancel any other traffic monitoring mode.
+ stopTrafficMonitoring();
+
+ if (!payload.has("ids")) {
+ return;
+ }
+
+ // Get the set of selected hosts and their intents.
+ ArrayNode ids = (ArrayNode) payload.path("ids");
+ selectedHosts = getHosts(ids);
+ selectedDevices = getDevices(ids);
+ selectedIntents = intentFilter.findPathIntents(
+ selectedHosts, selectedDevices, intentService.getIntents());
+ currentIntentIndex = -1;
+
+ if (haveSelectedIntents()) {
+ // Send a message to highlight all links of all monitored intents.
+ sendMessage(trafficMessage(new TrafficClass("primary", selectedIntents)));
+ }
+
+ // TODO: Re-introduce once the client click vs hover gesture stuff is sorted out.
+// String hover = string(payload, "hover");
+// if (!isNullOrEmpty(hover)) {
+// // If there is a hover node, include it in the selection and find intents.
+// processHoverExtendedSelection(sid, hover);
+// }
+ }
+ }
+
+ private final class ReqNextIntent extends RequestHandler {
+ private ReqNextIntent() {
+ super(REQ_NEXT_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ stopTrafficMonitoring();
+ requestAnotherRelatedIntent(+1);
+ }
+ }
+
+ private final class ReqPrevIntent extends RequestHandler {
+ private ReqPrevIntent() {
+ super(REQ_PREV_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ stopTrafficMonitoring();
+ requestAnotherRelatedIntent(-1);
+ }
+ }
+
+ private final class ReqSelectedIntentTraffic extends RequestHandler {
+ private ReqSelectedIntentTraffic() {
+ super(REQ_SEL_INTENT_TRAFFIC);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ trafficEvent =
+ new TrafficEvent(TrafficEvent.Type.SEL_INTENT, payload);
+ requestSelectedIntentTraffic();
+ startTrafficMonitoring();
+ }
+ }
+
+ private final class ReqAllTraffic extends RequestHandler {
+ private ReqAllTraffic() {
+ super(REQ_ALL_TRAFFIC);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ trafficEvent =
+ new TrafficEvent(TrafficEvent.Type.ALL_TRAFFIC, payload);
+ requestAllTraffic();
+ }
+ }
+
+ private final class ReqDevLinkFlows extends RequestHandler {
+ private ReqDevLinkFlows() {
+ super(REQ_DEV_LINK_FLOWS);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ trafficEvent =
+ new TrafficEvent(TrafficEvent.Type.DEV_LINK_FLOWS, payload);
+ requestDeviceLinkFlows(payload);
+ }
+ }
+
+ private final class CancelTraffic extends RequestHandler {
+ private CancelTraffic() {
+ super(CANCEL_TRAFFIC);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ selectedIntents = null;
+ sendMessage(trafficMessage());
+ stopTrafficMonitoring();
+ }
+ }
+
+ //=======================================================================
+
+
// Sends the specified data to the client.
protected synchronized void sendMessage(ObjectNode data) {
UiConnection connection = connection();
@@ -235,15 +494,12 @@
}
}
- private void sendAllInitialData() {
- addListeners();
- sendAllInstances(null);
- sendAllDevices();
- sendAllLinks();
- sendAllHosts();
-
+ // Subscribes for summary messages.
+ private synchronized void requestSummary(long sid) {
+ sendMessage(summmaryMessage(sid));
}
+
private void cancelAllRequests() {
stopSummaryMonitoring();
stopTrafficMonitoring();
@@ -296,77 +552,15 @@
}
}
- // Sends back device or host details.
- private void requestDetails(ObjectNode event) {
- ObjectNode payload = payload(event);
- String type = string(payload, "class", "unknown");
- long sid = number(event, "sid");
- if (type.equals("device")) {
- sendMessage(deviceDetails(deviceId(string(payload, "id")), sid));
- } else if (type.equals("host")) {
- sendMessage(hostDetails(hostId(string(payload, "id")), sid));
- }
- }
-
-
- // Creates host-to-host intent.
- private void createHostIntent(ObjectNode event) {
- ObjectNode payload = payload(event);
- long id = number(event, "sid");
- // TODO: add protection against device ids and non-existent hosts.
- HostId one = hostId(string(payload, "one"));
- HostId two = hostId(string(payload, "two"));
-
- HostToHostIntent intent =
- HostToHostIntent.builder()
- .appId(appId)
- .one(one)
- .two(two)
- .build();
-
- intentService.submit(intent);
- startMonitoringIntent(event, intent);
- }
-
- // Creates multi-source-to-single-dest intent.
- private void createMultiSourceIntent(ObjectNode event) {
- ObjectNode payload = payload(event);
- long id = number(event, "sid");
- // TODO: add protection against device ids and non-existent hosts.
- Set<HostId> src = getHostIds((ArrayNode) payload.path("src"));
- HostId dst = hostId(string(payload, "dst"));
- Host dstHost = hostService.getHost(dst);
-
- Set<ConnectPoint> ingressPoints = getHostLocations(src);
-
- // FIXME: clearly, this is not enough
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthDst(dstHost.mac()).build();
- TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
- MultiPointToSinglePointIntent intent =
- MultiPointToSinglePointIntent.builder()
- .appId(appId)
- .selector(selector)
- .treatment(treatment)
- .ingressPoints(ingressPoints)
- .egressPoint(dstHost.location())
- .build();
-
- intentService.submit(intent);
- startMonitoringIntent(event, intent);
- }
-
-
- private synchronized void startMonitoringIntent(ObjectNode event, Intent intent) {
+ private synchronized void startMonitoringIntent(Intent intent) {
selectedHosts = new HashSet<>();
selectedDevices = new HashSet<>();
selectedIntents = new ArrayList<>();
selectedIntents.add(intent);
currentIntentIndex = -1;
- requestAnotherRelatedIntent(event, +1);
- requestSelectedIntentTraffic(event);
+ requestAnotherRelatedIntent(+1);
+ requestSelectedIntentTraffic();
}
@@ -392,31 +586,27 @@
}
- private synchronized long startTrafficMonitoring(ObjectNode event) {
+ private synchronized void startTrafficMonitoring() {
stopTrafficMonitoring();
- trafficEvent = event;
trafficTask = new TrafficMonitor();
timer.schedule(trafficTask, TRAFFIC_FREQUENCY, TRAFFIC_FREQUENCY);
- return number(event, "sid");
}
private synchronized void stopTrafficMonitoring() {
if (trafficTask != null) {
trafficTask.cancel();
trafficTask = null;
- trafficEvent = null;
}
}
// Subscribes for host traffic messages.
- private synchronized void requestAllTraffic(ObjectNode event) {
- long sid = startTrafficMonitoring(event);
- sendMessage(trafficSummaryMessage(sid));
+ private synchronized void requestAllTraffic() {
+ startTrafficMonitoring();
+ sendMessage(trafficSummaryMessage());
}
- private void requestDeviceLinkFlows(ObjectNode event) {
- ObjectNode payload = payload(event);
- long sid = startTrafficMonitoring(event);
+ private void requestDeviceLinkFlows(ObjectNode payload) {
+ startTrafficMonitoring();
// Get the set of selected hosts and their intents.
ArrayNode ids = (ArrayNode) payload.path("ids");
@@ -424,47 +614,14 @@
Set<Device> devices = getDevices(ids);
// If there is a hover node, include it in the hosts and find intents.
- String hover = string(payload, "hover");
+ String hover = JsonUtils.string(payload, "hover");
if (!isNullOrEmpty(hover)) {
addHover(hosts, devices, hover);
}
- sendMessage(flowSummaryMessage(sid, devices));
+ sendMessage(flowSummaryMessage(devices));
}
- // Requests related intents message.
- private synchronized void requestRelatedIntents(ObjectNode event) {
- ObjectNode payload = payload(event);
- if (!payload.has("ids")) {
- return;
- }
-
- long sid = number(event, "sid");
-
- // Cancel any other traffic monitoring mode.
- stopTrafficMonitoring();
-
- // Get the set of selected hosts and their intents.
- ArrayNode ids = (ArrayNode) payload.path("ids");
- selectedHosts = getHosts(ids);
- selectedDevices = getDevices(ids);
- selectedIntents = intentFilter.findPathIntents(selectedHosts, selectedDevices,
- intentService.getIntents());
- currentIntentIndex = -1;
-
- if (haveSelectedIntents()) {
- // Send a message to highlight all links of all monitored intents.
- sendMessage(trafficMessage(sid, new TrafficClass("primary", selectedIntents)));
- }
-
- // FIXME: Re-introduce one the client click vs hover gesture stuff is sorted out.
-// String hover = string(payload, "hover");
-// if (!isNullOrEmpty(hover)) {
-// // If there is a hover node, include it in the selection and find intents.
-// processHoverExtendedSelection(sid, hover);
-// }
- }
-
private boolean haveSelectedIntents() {
return selectedIntents != null && !selectedIntents.isEmpty();
}
@@ -483,12 +640,12 @@
secondary.removeAll(primary);
// Send a message to highlight all links of all monitored intents.
- sendMessage(trafficMessage(sid, new TrafficClass("primary", primary),
+ sendMessage(trafficMessage(new TrafficClass("primary", primary),
new TrafficClass("secondary", secondary)));
}
// Requests next or previous related intent.
- private void requestAnotherRelatedIntent(ObjectNode event, int offset) {
+ private void requestAnotherRelatedIntent(int offset) {
if (haveSelectedIntents()) {
currentIntentIndex = currentIntentIndex + offset;
if (currentIntentIndex < 0) {
@@ -496,13 +653,13 @@
} else if (currentIntentIndex >= selectedIntents.size()) {
currentIntentIndex = 0;
}
- sendSelectedIntent(event);
+ sendSelectedIntent();
}
}
// Sends traffic information on the related intents with the currently
// selected intent highlighted.
- private void sendSelectedIntent(ObjectNode event) {
+ private void sendSelectedIntent() {
Intent selectedIntent = selectedIntents.get(currentIntentIndex);
log.info("Requested next intent {}", selectedIntent.id());
@@ -513,13 +670,12 @@
secondary.remove(selectedIntent);
// Send a message to highlight all links of the selected intent.
- sendMessage(trafficMessage(number(event, "sid"),
- new TrafficClass("primary", primary),
+ sendMessage(trafficMessage(new TrafficClass("primary", primary),
new TrafficClass("secondary", secondary)));
}
// Requests monitoring of traffic for the selected intent.
- private void requestSelectedIntentTraffic(ObjectNode event) {
+ private void requestSelectedIntentTraffic() {
if (haveSelectedIntents()) {
if (currentIntentIndex < 0) {
currentIntentIndex = 0;
@@ -531,61 +687,23 @@
primary.add(selectedIntent);
// Send a message to highlight all links of the selected intent.
- sendMessage(trafficMessage(number(event, "sid"),
- new TrafficClass("primary", primary, true)));
+ sendMessage(trafficMessage(new TrafficClass("primary", primary, true)));
}
}
- // Cancels sending traffic messages.
- private void cancelTraffic(ObjectNode event) {
- selectedIntents = null;
- sendMessage(trafficMessage(number(event, "sid")));
- stopTrafficMonitoring();
- }
-
-
- private synchronized long startSummaryMonitoring(ObjectNode event) {
+ private synchronized void startSummaryMonitoring() {
stopSummaryMonitoring();
- summaryEvent = event;
summaryTask = new SummaryMonitor();
timer.schedule(summaryTask, SUMMARY_FREQUENCY, SUMMARY_FREQUENCY);
- return number(event, "sid");
+ summaryRunning = true;
}
private synchronized void stopSummaryMonitoring() {
- if (summaryEvent != null) {
+ if (summaryTask != null) {
summaryTask.cancel();
summaryTask = null;
- summaryEvent = null;
}
- }
-
- // Subscribes for summary messages.
- private synchronized void requestSummary(ObjectNode event) {
- sendMessage(summmaryMessage(number(event, "sid")));
- }
-
-
- // Forces mastership role rebalancing.
- private void equalizeMasters(ObjectNode event) {
- directory.get(MastershipAdminService.class).balanceRoles();
- }
-
- // Sends a list of sprite names.
- private void sendSpriteList(ObjectNode event) {
- ObjectNode root = mapper.createObjectNode();
- ArrayNode names = mapper.createArrayNode();
- get(SpriteService.class).getNames().forEach(names::add);
- root.set("names", names);
- sendMessage(envelope("spriteListResponse", number(event, "sid"), root));
- }
-
- // Sends requested sprite data.
- private void sendSpriteData(ObjectNode event) {
- String name = event.path("payload").path("name").asText();
- ObjectNode root = mapper.createObjectNode();
- root.set("data", get(SpriteService.class).get(name));
- sendMessage(envelope("spriteDataResponse", number(event, "sid"), root));
+ summaryRunning = false;
}
@@ -666,8 +784,8 @@
private class InternalIntentListener implements IntentListener {
@Override
public void event(IntentEvent event) {
- if (trafficEvent != null) {
- requestSelectedIntentTraffic(trafficEvent);
+ if (trafficTask != null) {
+ requestSelectedIntentTraffic();
}
eventAccummulator.add(event);
}
@@ -681,19 +799,38 @@
}
}
+ // encapsulate
+ private static class TrafficEvent {
+ enum Type { ALL_TRAFFIC, DEV_LINK_FLOWS, SEL_INTENT }
+
+ private final Type type;
+ private final ObjectNode payload;
+
+ TrafficEvent(Type type, ObjectNode payload) {
+ this.type = type;
+ this.payload = payload;
+ }
+ }
+
// Periodic update of the traffic information
private class TrafficMonitor extends TimerTask {
@Override
public void run() {
try {
if (trafficEvent != null) {
- String type = string(trafficEvent, "event", "unknown");
- if (type.equals("requestAllTraffic")) {
- requestAllTraffic(trafficEvent);
- } else if (type.equals("requestDeviceLinkFlows")) {
- requestDeviceLinkFlows(trafficEvent);
- } else if (type.equals("requestSelectedIntentTraffic")) {
- requestSelectedIntentTraffic(trafficEvent);
+ switch (trafficEvent.type) {
+ case ALL_TRAFFIC:
+ requestAllTraffic();
+ break;
+ case DEV_LINK_FLOWS:
+ requestDeviceLinkFlows(trafficEvent.payload);
+ break;
+ case SEL_INTENT:
+ requestSelectedIntentTraffic();
+ break;
+ default:
+ // nothing to do
+ break;
}
}
} catch (Exception e) {
@@ -708,8 +845,8 @@
@Override
public void run() {
try {
- if (summaryEvent != null) {
- requestSummary(summaryEvent);
+ if (summaryRunning) {
+ requestSummary(0);
}
} catch (Exception e) {
log.warn("Unable to handle summary request due to {}", e.getMessage());
@@ -727,8 +864,8 @@
@Override
public void processItems(List<Event> items) {
try {
- if (summaryEvent != null) {
- sendMessage(summmaryMessage(0));
+ if (summaryRunning) {
+ requestSummary(0);
}
} catch (Exception e) {
log.warn("Unable to handle summary request due to {}", e.getMessage());
@@ -737,4 +874,3 @@
}
}
}
-
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
index 9bfc455..e0a9164 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
@@ -63,8 +63,9 @@
import org.onosproject.net.statistic.StatisticService;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyService;
+import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.UiConnection;
-import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -100,11 +101,13 @@
/**
* Facility for creating messages bound for the topology viewer.
*/
-public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
+public abstract class TopologyViewMessageHandlerBase extends UiMessageHandlerTwo {
- protected static final Logger log = LoggerFactory.getLogger(TopologyViewMessageHandlerBase.class);
+ protected static final Logger log =
+ LoggerFactory.getLogger(TopologyViewMessageHandlerBase.class);
- private static final ProviderId PID = new ProviderId("core", "org.onosproject.core", true);
+ private static final ProviderId PID =
+ new ProviderId("core", "org.onosproject.core", true);
private static final String COMPACT = "%s/%s-%s/%s";
private static final double KB = 1024;
@@ -133,15 +136,6 @@
private static Map<String, ObjectNode> metaUi = new ConcurrentHashMap<>();
/**
- * Creates a new message handler for the specified set of message types.
- *
- * @param messageTypes set of message types
- */
- protected TopologyViewMessageHandlerBase(Set<String> messageTypes) {
- super(messageTypes);
- }
-
- /**
* Returns read-only view of the meta-ui information.
*
* @return map of id to meta-ui mementos
@@ -168,26 +162,6 @@
version = ver.replace(".SNAPSHOT", "*").replaceFirst("~.*$", "");
}
- // Retrieves the payload from the specified event.
- protected ObjectNode payload(ObjectNode event) {
- return (ObjectNode) event.path("payload");
- }
-
- // Returns the specified node property as a number
- protected long number(ObjectNode node, String name) {
- return node.path(name).asLong();
- }
-
- // Returns the specified node property as a string.
- protected String string(ObjectNode node, String name) {
- return node.path(name).asText();
- }
-
- // Returns the specified node property as a string.
- protected String string(ObjectNode node, String name, String defaultValue) {
- return node.path(name).asText(defaultValue);
- }
-
// Returns the specified set of IP addresses as a string.
private String ip(Set<IpAddress> ipAddresses) {
Iterator<IpAddress> it = ipAddresses.iterator();
@@ -222,21 +196,11 @@
// Produces a log message event bound to the client.
private ObjectNode message(String severity, long id, String message) {
- return envelope("message", id,
- mapper.createObjectNode()
- .put("severity", severity)
- .put("message", message));
- }
+ ObjectNode payload = mapper.createObjectNode()
+ .put("severity", severity)
+ .put("message", message);
- // Puts the payload into an envelope and returns it.
- protected ObjectNode envelope(String type, long sid, ObjectNode payload) {
- ObjectNode event = mapper.createObjectNode();
- event.put("event", type);
- if (sid > 0) {
- event.put("sid", sid);
- }
- event.set("payload", payload);
- return event;
+ return JsonUtils.envelope("message", id, payload);
}
// Produces a set of all hosts listed in the specified JSON array.
@@ -320,7 +284,7 @@
((event.type() == INSTANCE_ADDED) ? "addInstance" :
((event.type() == INSTANCE_REMOVED ? "removeInstance" :
"addInstance")));
- return envelope(type, 0, payload);
+ return JsonUtils.envelope(type, 0, payload);
}
// Produces a device event message to the client.
@@ -347,7 +311,7 @@
String type = (event.type() == DEVICE_ADDED) ? "addDevice" :
((event.type() == DEVICE_REMOVED) ? "removeDevice" : "updateDevice");
- return envelope(type, 0, payload);
+ return JsonUtils.envelope(type, 0, payload);
}
// Produces a link event message to the client.
@@ -364,7 +328,7 @@
.put("dstPort", link.dst().port().toString());
String type = (event.type() == LINK_ADDED) ? "addLink" :
((event.type() == LINK_REMOVED) ? "removeLink" : "updateLink");
- return envelope(type, 0, payload);
+ return JsonUtils.envelope(type, 0, payload);
}
// Produces a host event message to the client.
@@ -385,7 +349,7 @@
String type = (event.type() == HOST_ADDED) ? "addHost" :
((event.type() == HOST_REMOVED) ? "removeHost" : "updateHost");
- return envelope(type, 0, payload);
+ return JsonUtils.envelope(type, 0, payload);
}
// Encodes the specified host location into a JSON object.
@@ -447,15 +411,15 @@
}
// Updates meta UI information for the specified object.
- protected void updateMetaUi(ObjectNode event) {
- ObjectNode payload = payload(event);
- metaUi.put(string(payload, "id"), (ObjectNode) payload.path("memento"));
+ protected void updateMetaUi(ObjectNode payload) {
+ metaUi.put(JsonUtils.string(payload, "id"),
+ JsonUtils.node(payload, "memento"));
}
// Returns summary response.
protected ObjectNode summmaryMessage(long sid) {
Topology topology = topologyService.currentTopology();
- return envelope("showSummary", sid,
+ return JsonUtils.envelope("showSummary", sid,
json("ONOS Summary", "node",
new Prop("Devices", format(topology.deviceCount())),
new Prop("Links", format(topology.linkCount())),
@@ -474,7 +438,7 @@
String name = annot.value(AnnotationKeys.NAME);
int portCount = deviceService.getPorts(deviceId).size();
int flowCount = getFlowCount(deviceId);
- return envelope("showDetails", sid,
+ return JsonUtils.envelope("showDetails", sid,
json(isNullOrEmpty(name) ? deviceId.toString() : name,
device.type().toString().toLowerCase(),
new Prop("URI", deviceId.toString()),
@@ -552,7 +516,7 @@
String type = annot.value(AnnotationKeys.TYPE);
String name = annot.value(AnnotationKeys.NAME);
String vlan = host.vlan().toString();
- return envelope("showDetails", sid,
+ return JsonUtils.envelope("showDetails", sid,
json(isNullOrEmpty(name) ? hostId.toString() : name,
isNullOrEmpty(type) ? "endstation" : type,
new Prop("MAC", host.mac().toString()),
@@ -565,7 +529,7 @@
// Produces JSON message to trigger traffic overview visualization
- protected ObjectNode trafficSummaryMessage(long sid) {
+ protected ObjectNode trafficSummaryMessage() {
ObjectNode payload = mapper.createObjectNode();
ArrayNode paths = mapper.createArrayNode();
payload.set("paths", paths);
@@ -603,7 +567,7 @@
}
}
}
- return envelope("showTraffic", sid, payload);
+ return JsonUtils.envelope("showTraffic", 0, payload);
}
private Collection<BiLink> consolidateLinks(Iterable<Link> links) {
@@ -615,7 +579,7 @@
}
// Produces JSON message to trigger flow overview visualization
- protected ObjectNode flowSummaryMessage(long sid, Set<Device> devices) {
+ protected ObjectNode flowSummaryMessage(Set<Device> devices) {
ObjectNode payload = mapper.createObjectNode();
ArrayNode paths = mapper.createArrayNode();
payload.set("paths", paths);
@@ -626,7 +590,7 @@
addLinkFlows(link, paths, counts.get(link));
}
}
- return envelope("showTraffic", sid, payload);
+ return JsonUtils.envelope("showTraffic", 0, payload);
}
private void addLinkFlows(Link link, ArrayNode paths, Integer count) {
@@ -644,7 +608,7 @@
// Produces JSON message to trigger traffic visualization
- protected ObjectNode trafficMessage(long sid, TrafficClass... trafficClasses) {
+ protected ObjectNode trafficMessage(TrafficClass... trafficClasses) {
ObjectNode payload = mapper.createObjectNode();
ArrayNode paths = mapper.createArrayNode();
payload.set("paths", paths);
@@ -670,7 +634,7 @@
((ArrayNode) pathNode.path("labels")).add(hasTraffic ? formatBytes(biLink.bytes) : "");
}
- return envelope("showTraffic", sid, payload);
+ return JsonUtils.envelope("showTraffic", 0, payload);
}
// Classifies the link traffic according to the specified classes.
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java b/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java
index 1fbbddf..d756da0 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java
@@ -24,8 +24,8 @@
import org.onosproject.cluster.ControllerNode;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiExtensionService;
-import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.UiMessageHandlerFactory;
+import org.onosproject.ui.UiMessageHandlerTwo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,7 +56,7 @@
private long lastActive = System.currentTimeMillis();
- private Map<String, UiMessageHandler> handlers;
+ private Map<String, UiMessageHandlerTwo> handlers;
/**
* Creates a new web-socket for serving data to GUI.
@@ -123,7 +123,7 @@
try {
ObjectNode message = (ObjectNode) mapper.reader().readTree(data);
String type = message.path("event").asText("unknown");
- UiMessageHandler handler = handlers.get(type);
+ UiMessageHandlerTwo handler = handlers.get(type);
if (handler != null) {
handler.process(message);
} else {