Bri Prebilic Cole
Committed by Gerrit Code Review

GUI -- Implemented Java backend device list sorting for tables.

Change-Id: I0ed18ce473e71dfc1b9188be47fe2f5062dd384f
...@@ -19,10 +19,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -19,10 +19,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
19 import com.fasterxml.jackson.databind.node.ArrayNode; 19 import com.fasterxml.jackson.databind.node.ArrayNode;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 import org.onlab.rest.BaseResource; 21 import org.onlab.rest.BaseResource;
22 -import org.onosproject.net.Annotations;
23 import org.onosproject.net.Device; 22 import org.onosproject.net.Device;
24 import org.onosproject.net.device.DeviceService; 23 import org.onosproject.net.device.DeviceService;
25 -import org.slf4j.Logger;
26 24
27 import javax.ws.rs.DefaultValue; 25 import javax.ws.rs.DefaultValue;
28 import javax.ws.rs.GET; 26 import javax.ws.rs.GET;
...@@ -31,8 +29,8 @@ import javax.ws.rs.Produces; ...@@ -31,8 +29,8 @@ import javax.ws.rs.Produces;
31 import javax.ws.rs.QueryParam; 29 import javax.ws.rs.QueryParam;
32 import javax.ws.rs.core.Response; 30 import javax.ws.rs.core.Response;
33 import java.util.ArrayList; 31 import java.util.ArrayList;
34 - 32 +import java.util.Arrays;
35 -import static org.slf4j.LoggerFactory.getLogger; 33 +import java.util.List;
36 34
37 /** 35 /**
38 * UI REST resource for interacting with the inventory of infrastructure devices. 36 * UI REST resource for interacting with the inventory of infrastructure devices.
...@@ -40,87 +38,42 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -40,87 +38,42 @@ import static org.slf4j.LoggerFactory.getLogger;
40 @Path("device") 38 @Path("device")
41 public class DeviceGuiResource extends BaseResource { 39 public class DeviceGuiResource extends BaseResource {
42 40
43 - private static final String ICON_ID_ONLINE = "deviceOnline"; 41 + private static final String DEVICES = "devices";
44 - private static final String ICON_ID_OFFLINE = "deviceOffline";
45 -
46 - private static final Logger log = getLogger(DeviceGuiResource.class);
47 42
48 - private final ObjectMapper mapper = new ObjectMapper(); 43 + private static final ObjectMapper MAPPER = new ObjectMapper();
49 44
50 45
51 // return list of devices 46 // return list of devices
52 @GET 47 @GET
53 @Produces("application/json") 48 @Produces("application/json")
54 public Response getDevices( 49 public Response getDevices(
55 - @DefaultValue("none") @QueryParam("sortCol") String colId, 50 + @DefaultValue("id") @QueryParam("sortCol") String colId,
56 - @DefaultValue("none") @QueryParam("sortDir") String dir 51 + @DefaultValue("asc") @QueryParam("sortDir") String dir
57 ) { 52 ) {
58 - ObjectNode rootNode = mapper.createObjectNode();
59 - ArrayNode devices = mapper.createArrayNode();
60 DeviceService service = get(DeviceService.class); 53 DeviceService service = get(DeviceService.class);
54 + TableRow[] rows = generateTableRows(service);
55 + RowComparator rc = new RowComparator(colId, RowComparator.direction(dir));
56 + Arrays.sort(rows, rc);
57 + ArrayNode devices = generateArrayNode(rows);
58 + ObjectNode rootNode = MAPPER.createObjectNode();
59 + rootNode.set(DEVICES, devices);
61 60
62 - // if no query parameters were given, get the data in whatever order
63 - if (colId.equals("none") || dir.equals("none")) {
64 - for (Device dev : service.getDevices()) {
65 - devices.add(deviceJson(service, dev));
66 - }
67 - } else {
68 - ArrayList<Device> sortedDevices = new ArrayList<>();
69 - for (Device dev : service.getDevices()) {
70 - sortedDevices.add(dev);
71 - }
72 - // now sort the arrayList based on the query parameters
73 - // then put each item into the ArrayNode devices
74 - // (pass in each device to deviceJson)
75 -
76 - // at this point, the sortedDevices list will be sorted
77 - for (Device dev : sortedDevices) {
78 - devices.add(deviceJson(service, dev));
79 - }
80 - }
81 -
82 - rootNode.set("devices", devices);
83 return Response.ok(rootNode.toString()).build(); 61 return Response.ok(rootNode.toString()).build();
84 } 62 }
85 63
86 - /** 64 + private ArrayNode generateArrayNode(TableRow[] rows) {
87 - * Returns a JSON node representing the specified device. 65 + ArrayNode devices = MAPPER.createArrayNode();
88 - * 66 + for (TableRow r : rows) {
89 - * @param device infrastructure device 67 + devices.add(r.toJsonNode());
90 - * @return JSON node 68 + }
91 - */ 69 + return devices;
92 - private ObjectNode deviceJson(DeviceService service, Device device) {
93 - boolean available = service.isAvailable(device.id());
94 - // pick the appropriate id for the icon to appear in the table row
95 - String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE;
96 -
97 - ObjectNode result = mapper.createObjectNode();
98 - result.put("id", device.id().toString())
99 - .put("available", available)
100 - .put("_iconid_available", iconId)
101 - .put("type", device.type().toString())
102 - .put("role", service.getRole(device.id()).toString())
103 - .put("mfr", device.manufacturer())
104 - .put("hw", device.hwVersion())
105 - .put("sw", device.swVersion())
106 - .put("serial", device.serialNumber())
107 - .set("annotations", annotations(mapper, device.annotations()));
108 - return result;
109 } 70 }
110 71
111 - /** 72 + private TableRow[] generateTableRows(DeviceService service) {
112 - * Produces a JSON object from the specified key/value annotations. 73 + List<TableRow> list = new ArrayList<>();
113 - * 74 + for (Device dev : service.getDevices()) {
114 - * @param mapper ObjectMapper to use while converting to JSON 75 + list.add(new DeviceTableRow(service, dev));
115 - * @param annotations key/value annotations
116 - * @return JSON object
117 - */
118 - private static ObjectNode annotations(ObjectMapper mapper, Annotations annotations) {
119 - ObjectNode result = mapper.createObjectNode();
120 - for (String key : annotations.keys()) {
121 - result.put(key, annotations.value(key));
122 } 76 }
123 - return result; 77 + return list.toArray(new TableRow[list.size()]);
124 } 78 }
125 -
126 } 79 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.gui;
18 +
19 +import com.fasterxml.jackson.databind.ObjectMapper;
20 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import org.onosproject.net.Device;
22 +import org.onosproject.net.device.DeviceService;
23 +
24 +import java.util.HashMap;
25 +import java.util.Map;
26 +
27 +public class DeviceTableRow implements TableRow {
28 +
29 + private static final String ID = "id";
30 + private static final String AVAILABLE = "available";
31 + private static final String AVAILABLE_IID = "_iconid_available";
32 + private static final String TYPE = "type";
33 + private static final String ROLE = "role";
34 + private static final String MFR = "mfr";
35 + private static final String HW = "hw";
36 + private static final String SW = "sw";
37 + private static final String SERIAL = "serial";
38 + private static final String PROTOCOL = "protocol";
39 +
40 + private static final String ICON_ID_ONLINE = "deviceOnline";
41 + private static final String ICON_ID_OFFLINE = "deviceOffline";
42 +
43 + private static final ObjectMapper MAPPER = new ObjectMapper();
44 +
45 + private final Map<String, String> data = new HashMap<>();
46 +
47 + public DeviceTableRow(DeviceService service, Device d) {
48 + boolean available = service.isAvailable(d.id());
49 + String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE;
50 +
51 + data.put(ID, d.id().toString());
52 + data.put(AVAILABLE, Boolean.toString(available));
53 + data.put(AVAILABLE_IID, iconId);
54 + data.put(TYPE, d.type().toString());
55 + data.put(ROLE, service.getRole(d.id()).toString());
56 + data.put(MFR, d.manufacturer());
57 + data.put(HW, d.hwVersion());
58 + data.put(SW, d.swVersion());
59 + data.put(SERIAL, d.serialNumber());
60 + data.put(PROTOCOL, d.annotations().value(PROTOCOL));
61 + }
62 +
63 + @Override
64 + public String get(String key) {
65 + return data.get(key);
66 + }
67 +
68 + @Override
69 + public ObjectNode toJsonNode() {
70 + ObjectNode result = MAPPER.createObjectNode();
71 + result.put(ID, data.get(ID));
72 + result.put(AVAILABLE, data.get(AVAILABLE));
73 + result.put(AVAILABLE_IID, data.get(AVAILABLE_IID));
74 + result.put(TYPE, data.get(TYPE));
75 + result.put(ROLE, data.get(ROLE));
76 + result.put(MFR, data.get(MFR));
77 + result.put(HW, data.get(HW));
78 + result.put(SW, data.get(SW));
79 + result.put(SERIAL, data.get(SERIAL));
80 + result.put(PROTOCOL, data.get(PROTOCOL));
81 + return result;
82 + }
83 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.gui;
18 +
19 +import java.util.Comparator;
20 +
21 +/**
22 + * Comparator for {@link TableRow}.
23 + */
24 +public class RowComparator implements Comparator<TableRow> {
25 + public static enum Direction { ASC, DESC }
26 +
27 + public static final String DESC_STR = "desc";
28 +
29 + private final String colId;
30 + private final Direction dir;
31 +
32 + public RowComparator(String colId, Direction dir) {
33 + if (colId == null || dir == null) {
34 + throw new NullPointerException("Null parameters not allowed");
35 + }
36 + this.colId = colId;
37 + this.dir = dir;
38 + }
39 +
40 + @Override
41 + public int compare(TableRow a, TableRow b) {
42 + String cellA = a.get(colId);
43 + String cellB = b.get(colId);
44 +
45 + if (dir.equals(Direction.ASC)) {
46 + return cellA.compareTo(cellB);
47 + }
48 + return cellB.compareTo(cellA);
49 + }
50 +
51 + /**
52 + * Returns the sort direction constant for the given string.
53 + * The expected strings are "asc" and "desc"; defaults to "asc".
54 + *
55 + * @param s the direction as a string
56 + * @return the constant
57 + */
58 + public static Direction direction(String s) {
59 + return DESC_STR.equals(s) ? Direction.DESC : Direction.ASC;
60 + }
61 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.gui;
18 +
19 +
20 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 +
22 +/**
23 + * Defines a table row abstraction to support sortable tables on the GUI.
24 + */
25 +public interface TableRow {
26 + /**
27 + * Returns the value of the cell for the given column ID.
28 + *
29 + * @param key the column ID
30 + * @return the cell value
31 + */
32 + String get(String key);
33 +
34 + /**
35 + * Returns this table row in the form of a JSON object.
36 + *
37 + * @return the JSON node
38 + */
39 + ObjectNode toJsonNode();
40 +}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 <thead> 9 <thead>
10 <tr> 10 <tr>
11 <th colId="available"></th> 11 <th colId="available"></th>
12 - <th colId="id" sortable>URI</th> 12 + <th colId="id" sortable>Device ID</th>
13 <th colId="mfr" sortable>Vendor</th> 13 <th colId="mfr" sortable>Vendor</th>
14 <th colId="hw" sortable>Hardware Version</th> 14 <th colId="hw" sortable>Hardware Version</th>
15 <th colId="sw" sortable>Software Version</th> 15 <th colId="sw" sortable>Software Version</th>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
27 <td>{{dev.hw}}</td> 27 <td>{{dev.hw}}</td>
28 <td>{{dev.sw}}</td> 28 <td>{{dev.sw}}</td>
29 <td>{{dev.serial}}</td> 29 <td>{{dev.serial}}</td>
30 - <td>{{dev.annotations.protocol}}</td> 30 + <td>{{dev.protocol}}</td>
31 </tr> 31 </tr>
32 </tbody> 32 </tbody>
33 </table> 33 </table>
......