ONOS-6327: Implemented details panel for host view.
- WIP: still have to render the host details in the panel.
- YakShaving:
* augmented ConnectPoint to implement Comparable
* cleaned up ConnectPointTest
Change-Id: I5c901099319820e08af812807ff65bf5dac1fb23
diff --git a/core/api/src/main/java/org/onosproject/net/ConnectPoint.java b/core/api/src/main/java/org/onosproject/net/ConnectPoint.java
index 13471ec..f12bf1b 100644
--- a/core/api/src/main/java/org/onosproject/net/ConnectPoint.java
+++ b/core/api/src/main/java/org/onosproject/net/ConnectPoint.java
@@ -24,7 +24,7 @@
* Abstraction of a network connection point expressed as a pair of the
* network element identifier and port number.
*/
-public class ConnectPoint {
+public class ConnectPoint implements Comparable<ConnectPoint> {
private final ElementId elementId;
private final PortNumber portNumber;
@@ -167,4 +167,13 @@
return elementId + "/" + portNumber;
}
+ @Override
+ public int compareTo(ConnectPoint o) {
+ int result = deviceId().toString().compareTo(o.deviceId().toString());
+ if (result == 0) {
+ long delta = port().toLong() - o.port().toLong();
+ result = delta == 0 ? 0 : (delta < 0 ? -1 : +1);
+ }
+ return result;
+ }
}
diff --git a/core/api/src/test/java/org/onosproject/net/ConnectPointTest.java b/core/api/src/test/java/org/onosproject/net/ConnectPointTest.java
index ee55723..74b162e 100644
--- a/core/api/src/test/java/org/onosproject/net/ConnectPointTest.java
+++ b/core/api/src/test/java/org/onosproject/net/ConnectPointTest.java
@@ -21,6 +21,9 @@
import static junit.framework.TestCase.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.ConnectPointTest.Relate.AFTER;
+import static org.onosproject.net.ConnectPointTest.Relate.BEFORE;
+import static org.onosproject.net.ConnectPointTest.Relate.SAME_AS;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.PortNumber.portNumber;
@@ -34,9 +37,13 @@
private static final PortNumber P1 = portNumber(1);
private static final PortNumber P2 = portNumber(2);
+ private ConnectPoint cp(DeviceId d, PortNumber p) {
+ return new ConnectPoint(d, p);
+ }
+
@Test
public void basics() {
- ConnectPoint p = new ConnectPoint(DID1, P2);
+ ConnectPoint p = cp(DID1, P2);
assertEquals("incorrect element id", DID1, p.deviceId());
assertEquals("incorrect element id", P2, p.port());
}
@@ -44,9 +51,9 @@
@Test
public void testEquality() {
new EqualsTester()
- .addEqualityGroup(new ConnectPoint(DID1, P1), new ConnectPoint(DID1, P1))
- .addEqualityGroup(new ConnectPoint(DID1, P2), new ConnectPoint(DID1, P2))
- .addEqualityGroup(new ConnectPoint(DID2, P1), new ConnectPoint(DID2, P1))
+ .addEqualityGroup(cp(DID1, P1), cp(DID1, P1))
+ .addEqualityGroup(cp(DID1, P2), cp(DID1, P2))
+ .addEqualityGroup(cp(DID2, P1), cp(DID2, P1))
.testEquals();
}
@@ -107,4 +114,34 @@
assertTrue(true);
}
}
+
+ enum Relate { BEFORE, SAME_AS, AFTER }
+
+ private void checkComparison(ConnectPoint cpA, Relate r, ConnectPoint cpB) {
+ switch (r) {
+ case BEFORE:
+ assertTrue("Bad before", cpA.compareTo(cpB) < 0);
+ break;
+ case SAME_AS:
+ assertTrue("Bad same_as", cpA.compareTo(cpB) == 0);
+ break;
+ case AFTER:
+ assertTrue("Bad after", cpA.compareTo(cpB) > 0);
+ break;
+ default:
+ fail("Bad relation");
+ }
+ }
+
+ @Test
+ public void comparator() {
+ checkComparison(cp(DID1, P1), SAME_AS, cp(DID1, P1));
+ checkComparison(cp(DID1, P1), BEFORE, cp(DID1, P2));
+ checkComparison(cp(DID1, P2), AFTER, cp(DID1, P1));
+
+ checkComparison(cp(DID1, P1), BEFORE, cp(DID2, P1));
+ checkComparison(cp(DID1, P2), BEFORE, cp(DID2, P1));
+ checkComparison(cp(DID1, P1), BEFORE, cp(DID2, P2));
+ checkComparison(cp(DID1, P2), BEFORE, cp(DID2, P2));
+ }
}
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 6e821f4..169b89f 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
@@ -15,11 +15,14 @@
*/
package org.onosproject.ui.impl;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.IpAddress;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
import org.onosproject.net.host.HostService;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler;
@@ -27,11 +30,17 @@
import org.onosproject.ui.table.TableModel;
import org.onosproject.ui.table.TableRequestHandler;
import org.onosproject.ui.table.cell.HostLocationFormatter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
import java.util.Set;
import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onosproject.net.HostId.hostId;
/**
* Message handler for host view related messages.
@@ -42,22 +51,51 @@
private static final String HOST_DATA_RESP = "hostDataResponse";
private static final String HOSTS = "hosts";
+ private static final String HOST_DETAILS_REQ = "hostDetailsRequest";
+ private static final String HOST_DETAILS_RESP = "hostDetailsResponse";
+ private static final String DETAILS = "details";
+
+ private static final String HOST_NAME_CHANGE_REQ = "hostNameChangeRequest";
+ private static final String HOST_NAME_CHANGE_RESP = "hostNameChangeResponse";
+
private static final String TYPE_IID = "_iconid_type";
+ private static final String NAME = "name";
private static final String ID = "id";
private static final String MAC = "mac";
private static final String VLAN = "vlan";
private static final String IPS = "ips";
private static final String LOCATION = "location";
+ private static final String LOCATIONS = "locations";
+ private static final String CONFIGURED = "configured";
+
private static final String HOST_ICON_PREFIX = "hostIcon_";
private static final String[] COL_IDS = {
- TYPE_IID, ID, MAC, VLAN, IPS, LOCATION
+ TYPE_IID, NAME, ID, MAC, VLAN, CONFIGURED, IPS, LOCATION
};
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
@Override
protected Collection<RequestHandler> createRequestHandlers() {
- return ImmutableSet.of(new HostDataRequest());
+ return ImmutableSet.of(
+ new HostDataRequest(),
+ new DetailRequestHandler(),
+ new NameChangeHandler()
+ );
+ }
+
+ private String getTypeIconId(Host host) {
+ String hostType = host.annotations().value(AnnotationKeys.TYPE);
+ return HOST_ICON_PREFIX +
+ (isNullOrEmpty(hostType) ? "endstation" : hostType);
+ }
+
+ // returns the "friendly name" for the host
+ private String getHostName(Host host) {
+ // TODO: acutally use the name field (not just the ID)
+ return host.id().toString();
}
// handler for host table requests
@@ -96,17 +134,14 @@
private void populateRow(TableModel.Row row, Host host) {
row.cell(TYPE_IID, getTypeIconId(host))
+ .cell(NAME, getHostName(host))
.cell(ID, host.id())
.cell(MAC, host.mac())
.cell(VLAN, host.vlan())
+ .cell(CONFIGURED, host.configured())
.cell(IPS, host.ipAddresses())
.cell(LOCATION, host.location());
- }
-
- private String getTypeIconId(Host host) {
- String hostType = host.annotations().value(AnnotationKeys.TYPE);
- return HOST_ICON_PREFIX +
- (isNullOrEmpty(hostType) ? "endstation" : hostType);
+ // Note: leave complete list of all LOCATIONS to the details panel
}
private final class IpSetFormatter implements CellFormatter {
@@ -123,8 +158,7 @@
sb.append(ip.toString())
.append(COMMA);
}
- removeTrailingComma(sb);
- return sb.toString();
+ return removeTrailingComma(sb).toString();
}
private StringBuilder removeTrailingComma(StringBuilder sb) {
@@ -134,4 +168,65 @@
}
}
}
+
+
+ private final class DetailRequestHandler extends RequestHandler {
+ private DetailRequestHandler() {
+ super(HOST_DETAILS_REQ);
+ }
+
+ @Override
+ public void process(ObjectNode payload) {
+ String id = string(payload, ID, "");
+
+ HostId hostId = hostId(id);
+ HostService service = get(HostService.class);
+ Host host = service.getHost(hostId);
+ ObjectNode data = objectNode();
+
+ data.put(TYPE_IID, getTypeIconId(host))
+ .put(NAME, getHostName(host))
+ .put(ID, hostId.toString())
+ .put(MAC, host.mac().toString())
+ .put(VLAN, host.vlan().toString())
+ .put(CONFIGURED, host.configured())
+ .put(LOCATION, host.location().toString());
+
+ List<IpAddress> sortedIps = new ArrayList<>(host.ipAddresses());
+ Collections.sort(sortedIps);
+ ArrayNode ips = arrayNode();
+ for (IpAddress ip : sortedIps) {
+ ips.add(ip.toString());
+ }
+ data.set(IPS, ips);
+
+ List<HostLocation> sortedLocs = new ArrayList<>(host.locations());
+ Collections.sort(sortedLocs);
+ ArrayNode locs = arrayNode();
+ for (HostLocation hl : sortedLocs) {
+ locs.add(hl.toString());
+ }
+ data.set(LOCATIONS, locs);
+
+ ObjectNode root = objectNode();
+ root.set(DETAILS, data);
+
+ sendMessage(HOST_DETAILS_RESP, root);
+ }
+ }
+
+ private final class NameChangeHandler extends RequestHandler {
+ public NameChangeHandler() {
+ super(HOST_NAME_CHANGE_REQ);
+ }
+
+ @Override
+ public void process(ObjectNode payload) {
+ // TODO:
+
+ ObjectNode root = objectNode();
+
+ sendMessage(HOST_NAME_CHANGE_RESP, root);
+ }
+ }
}
diff --git a/web/gui/src/main/webapp/app/view/host/host.html b/web/gui/src/main/webapp/app/view/host/host.html
index e88efa3..85b8b5e 100644
--- a/web/gui/src/main/webapp/app/view/host/host.html
+++ b/web/gui/src/main/webapp/app/view/host/host.html
@@ -15,9 +15,11 @@
<table>
<tr>
<td colId="type" class="table-icon"></td>
+ <td colId="name" sortable>Friendly Name </td>
<td colId="id" sortable>Host ID </td>
<td colId="mac" sortable>MAC Address </td>
<td colId="vlan" sortable>VLAN ID </td>
+ <td colId="configured" sortable>Configured </td>
<td colId="ips" sortable>IP Addresses </td>
<td colId="location" sortable>Location </td>
</tr>
@@ -27,7 +29,7 @@
<div class="table-body">
<table onos-flash-changes id-prop="id">
<tr ng-if="!tableData.length" class="no-data">
- <td colspan="6">
+ <td colspan="8">
{{annots.no_rows_msg}}
</td>
</tr>
@@ -39,9 +41,11 @@
<td class="table-icon">
<div icon icon-id="{{host._iconid_type}}"></div>
</td>
+ <td>{{host.name}}</td>
<td>{{host.id}}</td>
<td>{{host.mac}}</td>
<td>{{host.vlan}}</td>
+ <td>{{host.configured}}</td>
<td>{{host.ips}}</td>
<td>{{host.location}}</td>
</tr>
diff --git a/web/gui/src/main/webapp/app/view/host/host.js b/web/gui/src/main/webapp/app/view/host/host.js
index 537bc13..ee23f00 100644
--- a/web/gui/src/main/webapp/app/view/host/host.js
+++ b/web/gui/src/main/webapp/app/view/host/host.js
@@ -148,6 +148,8 @@
setUpPanel();
populateTop(details);
detailsPanel.height(pHeight);
+ // configure width based on content.. for now hardcoded
+ detailsPanel.width(600);
}
function respDetailsCb(data) {