Committed by
Gerrit Code Review
GUI -- Preliminary work for converting tabular views to use the shared web-socke…
…t rather than via REST. WIP. Change-Id: I68de98e8df0a2bbcebe15ad9015ce6b4df43d81c
Showing
16 changed files
with
465 additions
and
139 deletions
| ... | @@ -29,6 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -29,6 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 29 | * interface client. | 29 | * interface client. |
| 30 | * <p> | 30 | * <p> |
| 31 | * The message is a JSON object with the following structure: | 31 | * The message is a JSON object with the following structure: |
| 32 | + * </p> | ||
| 32 | * <pre> | 33 | * <pre> |
| 33 | * { | 34 | * { |
| 34 | * "type": "<em>event-type</em>", | 35 | * "type": "<em>event-type</em>", |
| ... | @@ -45,7 +46,9 @@ public abstract class UiMessageHandler { | ... | @@ -45,7 +46,9 @@ public abstract class UiMessageHandler { |
| 45 | private UiConnection connection; | 46 | private UiConnection connection; |
| 46 | private ServiceDirectory directory; | 47 | private ServiceDirectory directory; |
| 47 | 48 | ||
| 48 | - /** Mapper for creating ObjectNodes and ArrayNodes etc. */ | 49 | + /** |
| 50 | + * Mapper for creating ObjectNodes and ArrayNodes etc. | ||
| 51 | + */ | ||
| 49 | protected final ObjectMapper mapper = new ObjectMapper(); | 52 | protected final ObjectMapper mapper = new ObjectMapper(); |
| 50 | 53 | ||
| 51 | /** | 54 | /** |
| ... | @@ -129,8 +132,8 @@ public abstract class UiMessageHandler { | ... | @@ -129,8 +132,8 @@ public abstract class UiMessageHandler { |
| 129 | * Wraps a message payload into an event structure for the given event | 132 | * Wraps a message payload into an event structure for the given event |
| 130 | * type and sequence ID. Generally the | 133 | * type and sequence ID. Generally the |
| 131 | * | 134 | * |
| 132 | - * @param type event type | 135 | + * @param type event type |
| 133 | - * @param sid sequence ID | 136 | + * @param sid sequence ID |
| 134 | * @param payload event payload | 137 | * @param payload event payload |
| 135 | * @return the object node representation | 138 | * @return the object node representation |
| 136 | */ | 139 | */ |
| ... | @@ -144,4 +147,48 @@ public abstract class UiMessageHandler { | ... | @@ -144,4 +147,48 @@ public abstract class UiMessageHandler { |
| 144 | return event; | 147 | return event; |
| 145 | } | 148 | } |
| 146 | 149 | ||
| 150 | + /** | ||
| 151 | + * Retrieves the payload from the specified event. | ||
| 152 | + * | ||
| 153 | + * @param event message event | ||
| 154 | + * @return extracted payload object | ||
| 155 | + */ | ||
| 156 | + protected ObjectNode payload(ObjectNode event) { | ||
| 157 | + return (ObjectNode) event.path("payload"); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + /** | ||
| 161 | + * Returns the specified node property as a number. | ||
| 162 | + * | ||
| 163 | + * @param node message event | ||
| 164 | + * @param name property name | ||
| 165 | + * @return property as number | ||
| 166 | + */ | ||
| 167 | + protected long number(ObjectNode node, String name) { | ||
| 168 | + return node.path(name).asLong(); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + /** | ||
| 172 | + * Returns the specified node property as a string. | ||
| 173 | + * | ||
| 174 | + * @param node message event | ||
| 175 | + * @param name property name | ||
| 176 | + * @return property as a string | ||
| 177 | + */ | ||
| 178 | + protected String string(ObjectNode node, String name) { | ||
| 179 | + return node.path(name).asText(); | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + /** | ||
| 183 | + * Returns the specified node property as a string with a default fallback. | ||
| 184 | + * | ||
| 185 | + * @param node message event | ||
| 186 | + * @param name property name | ||
| 187 | + * @param defaultValue fallback value if property is absent | ||
| 188 | + * @return property as a string | ||
| 189 | + */ | ||
| 190 | + protected String string(ObjectNode node, String name, String defaultValue) { | ||
| 191 | + return node.path(name).asText(defaultValue); | ||
| 192 | + } | ||
| 193 | + | ||
| 147 | } | 194 | } | ... | ... |
| 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 | +package org.onosproject.ui.impl; | ||
| 17 | + | ||
| 18 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 19 | +import org.onosproject.ui.UiMessageHandler; | ||
| 20 | + | ||
| 21 | +import java.util.Set; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * Base message handler for tabular views. | ||
| 25 | + */ | ||
| 26 | +public abstract class AbstractTabularViewMessageHandler extends UiMessageHandler { | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Creates a new tabular view message handler. | ||
| 30 | + * | ||
| 31 | + * @param messageTypes set of message types | ||
| 32 | + */ | ||
| 33 | + protected AbstractTabularViewMessageHandler(Set<String> messageTypes) { | ||
| 34 | + super(messageTypes); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Produces JSON from the specified array of rows. | ||
| 39 | + * | ||
| 40 | + * @param rows table rows | ||
| 41 | + * @return JSON array | ||
| 42 | + */ | ||
| 43 | + protected ArrayNode generateArrayNode(TableRow[] rows) { | ||
| 44 | + ArrayNode array = mapper.createArrayNode(); | ||
| 45 | + for (TableRow r : rows) { | ||
| 46 | + array.add(r.toJsonNode()); | ||
| 47 | + } | ||
| 48 | + return array; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + // TODO: possibly convert this into just a toolbox class | ||
| 52 | + // TODO: extract and generalize other table constructs | ||
| 53 | +} |
| 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 | -package org.onosproject.ui.impl; | ||
| 17 | - | ||
| 18 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
| 19 | -import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 20 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 21 | -import org.onlab.rest.BaseResource; | ||
| 22 | -import org.onosproject.net.Device; | ||
| 23 | -import org.onosproject.net.device.DeviceService; | ||
| 24 | - | ||
| 25 | -import javax.ws.rs.DefaultValue; | ||
| 26 | -import javax.ws.rs.GET; | ||
| 27 | -import javax.ws.rs.Path; | ||
| 28 | -import javax.ws.rs.Produces; | ||
| 29 | -import javax.ws.rs.QueryParam; | ||
| 30 | -import javax.ws.rs.core.Response; | ||
| 31 | -import java.util.ArrayList; | ||
| 32 | -import java.util.Arrays; | ||
| 33 | -import java.util.List; | ||
| 34 | - | ||
| 35 | -/** | ||
| 36 | - * UI REST resource for interacting with the inventory of infrastructure devices. | ||
| 37 | - */ | ||
| 38 | -@Path("device") | ||
| 39 | -public class DeviceGuiResource extends BaseResource { | ||
| 40 | - | ||
| 41 | - private static final String DEVICES = "devices"; | ||
| 42 | - | ||
| 43 | - private static final ObjectMapper MAPPER = new ObjectMapper(); | ||
| 44 | - | ||
| 45 | - | ||
| 46 | - // return the list of devices in appropriate sorted order | ||
| 47 | - @GET | ||
| 48 | - @Produces("application/json") | ||
| 49 | - public Response getDevices( | ||
| 50 | - @DefaultValue("id") @QueryParam("sortCol") String colId, | ||
| 51 | - @DefaultValue("asc") @QueryParam("sortDir") String dir | ||
| 52 | - ) { | ||
| 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); | ||
| 60 | - | ||
| 61 | - return Response.ok(rootNode.toString()).build(); | ||
| 62 | - } | ||
| 63 | - | ||
| 64 | - private ArrayNode generateArrayNode(TableRow[] rows) { | ||
| 65 | - ArrayNode devices = MAPPER.createArrayNode(); | ||
| 66 | - for (TableRow r : rows) { | ||
| 67 | - devices.add(r.toJsonNode()); | ||
| 68 | - } | ||
| 69 | - return devices; | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - private TableRow[] generateTableRows(DeviceService service) { | ||
| 73 | - List<TableRow> list = new ArrayList<>(); | ||
| 74 | - for (Device dev : service.getDevices()) { | ||
| 75 | - list.add(new DeviceTableRow(service, dev)); | ||
| 76 | - } | ||
| 77 | - return list.toArray(new TableRow[list.size()]); | ||
| 78 | - } | ||
| 79 | -} |
| ... | @@ -13,61 +13,106 @@ | ... | @@ -13,61 +13,106 @@ |
| 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. | 14 | * limitations under the License. |
| 15 | */ | 15 | */ |
| 16 | - | ||
| 17 | package org.onosproject.ui.impl; | 16 | package org.onosproject.ui.impl; |
| 18 | 17 | ||
| 18 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 20 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | import org.onosproject.net.Device; | 21 | import org.onosproject.net.Device; |
| 20 | import org.onosproject.net.device.DeviceService; | 22 | import org.onosproject.net.device.DeviceService; |
| 21 | 23 | ||
| 24 | +import java.util.ArrayList; | ||
| 25 | +import java.util.Arrays; | ||
| 26 | +import java.util.List; | ||
| 27 | + | ||
| 22 | /** | 28 | /** |
| 23 | - * TableRow implementation for {@link Device devices}. | 29 | + * Message handler for device view related messages. |
| 24 | */ | 30 | */ |
| 25 | -public class DeviceTableRow extends AbstractTableRow { | 31 | +public class DeviceViewMessageHandler extends AbstractTabularViewMessageHandler { |
| 26 | - | ||
| 27 | - private static final String ID = "id"; | ||
| 28 | - private static final String AVAILABLE = "available"; | ||
| 29 | - private static final String AVAILABLE_IID = "_iconid_available"; | ||
| 30 | - private static final String TYPE_IID = "_iconid_type"; | ||
| 31 | - private static final String DEV_ICON_PREFIX = "devIcon_"; | ||
| 32 | - private static final String ROLE = "role"; | ||
| 33 | - private static final String MFR = "mfr"; | ||
| 34 | - private static final String HW = "hw"; | ||
| 35 | - private static final String SW = "sw"; | ||
| 36 | - private static final String SERIAL = "serial"; | ||
| 37 | - private static final String PROTOCOL = "protocol"; | ||
| 38 | - private static final String CHASSISID = "chassisid"; | ||
| 39 | - | ||
| 40 | - private static final String[] COL_IDS = { | ||
| 41 | - ID, AVAILABLE, AVAILABLE_IID, TYPE_IID, ROLE, | ||
| 42 | - MFR, HW, SW, SERIAL, PROTOCOL, CHASSISID | ||
| 43 | - }; | ||
| 44 | - | ||
| 45 | - private static final String ICON_ID_ONLINE = "deviceOnline"; | ||
| 46 | - private static final String ICON_ID_OFFLINE = "deviceOffline"; | ||
| 47 | - | ||
| 48 | - public DeviceTableRow(DeviceService service, Device d) { | ||
| 49 | - boolean available = service.isAvailable(d.id()); | ||
| 50 | - String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE; | ||
| 51 | - | ||
| 52 | - add(ID, d.id().toString()); | ||
| 53 | - add(AVAILABLE, Boolean.toString(available)); | ||
| 54 | - add(AVAILABLE_IID, iconId); | ||
| 55 | - add(TYPE_IID, getTypeIconId(d)); | ||
| 56 | - add(ROLE, service.getRole(d.id()).toString()); | ||
| 57 | - add(MFR, d.manufacturer()); | ||
| 58 | - add(HW, d.hwVersion()); | ||
| 59 | - add(SW, d.swVersion()); | ||
| 60 | - add(SERIAL, d.serialNumber()); | ||
| 61 | - add(PROTOCOL, d.annotations().value(PROTOCOL)); | ||
| 62 | - add(CHASSISID, d.chassisId().toString()); | ||
| 63 | - } | ||
| 64 | 32 | ||
| 65 | - private String getTypeIconId(Device d) { | 33 | + /** |
| 66 | - return DEV_ICON_PREFIX + d.type().toString(); | 34 | + * Creates a new message handler for the device messages. |
| 35 | + */ | ||
| 36 | + protected DeviceViewMessageHandler() { | ||
| 37 | + super(ImmutableSet.of("deviceDataRequest")); | ||
| 67 | } | 38 | } |
| 68 | 39 | ||
| 69 | @Override | 40 | @Override |
| 70 | - protected String[] columnIds() { | 41 | + public void process(ObjectNode message) { |
| 71 | - return COL_IDS; | 42 | + ObjectNode payload = payload(message); |
| 43 | + String sortCol = string(payload, "sortCol", "id"); | ||
| 44 | + String sortDir = string(payload, "sortDir", "asc"); | ||
| 45 | + | ||
| 46 | + DeviceService service = get(DeviceService.class); | ||
| 47 | + TableRow[] rows = generateTableRows(service); | ||
| 48 | + RowComparator rc = new RowComparator(sortCol, RowComparator.direction(sortDir)); | ||
| 49 | + Arrays.sort(rows, rc); | ||
| 50 | + ArrayNode devices = generateArrayNode(rows); | ||
| 51 | + ObjectNode rootNode = mapper.createObjectNode(); | ||
| 52 | + rootNode.set("devices", devices); | ||
| 53 | + | ||
| 54 | + connection().sendMessage("deviceDataResponse", 0, rootNode); | ||
| 72 | } | 55 | } |
| 56 | + | ||
| 57 | + private TableRow[] generateTableRows(DeviceService service) { | ||
| 58 | + List<TableRow> list = new ArrayList<>(); | ||
| 59 | + for (Device dev : service.getDevices()) { | ||
| 60 | + list.add(new DeviceTableRow(service, dev)); | ||
| 61 | + } | ||
| 62 | + return list.toArray(new TableRow[list.size()]); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * TableRow implementation for {@link Device devices}. | ||
| 67 | + */ | ||
| 68 | + private static class DeviceTableRow extends AbstractTableRow { | ||
| 69 | + | ||
| 70 | + private static final String ID = "id"; | ||
| 71 | + private static final String AVAILABLE = "available"; | ||
| 72 | + private static final String AVAILABLE_IID = "_iconid_available"; | ||
| 73 | + private static final String TYPE_IID = "_iconid_type"; | ||
| 74 | + private static final String DEV_ICON_PREFIX = "devIcon_"; | ||
| 75 | + private static final String ROLE = "role"; | ||
| 76 | + private static final String MFR = "mfr"; | ||
| 77 | + private static final String HW = "hw"; | ||
| 78 | + private static final String SW = "sw"; | ||
| 79 | + private static final String SERIAL = "serial"; | ||
| 80 | + private static final String PROTOCOL = "protocol"; | ||
| 81 | + private static final String CHASSISID = "chassisid"; | ||
| 82 | + | ||
| 83 | + private static final String[] COL_IDS = { | ||
| 84 | + ID, AVAILABLE, AVAILABLE_IID, TYPE_IID, ROLE, | ||
| 85 | + MFR, HW, SW, SERIAL, PROTOCOL, CHASSISID | ||
| 86 | + }; | ||
| 87 | + | ||
| 88 | + private static final String ICON_ID_ONLINE = "deviceOnline"; | ||
| 89 | + private static final String ICON_ID_OFFLINE = "deviceOffline"; | ||
| 90 | + | ||
| 91 | + public DeviceTableRow(DeviceService service, Device d) { | ||
| 92 | + boolean available = service.isAvailable(d.id()); | ||
| 93 | + String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE; | ||
| 94 | + | ||
| 95 | + add(ID, d.id().toString()); | ||
| 96 | + add(AVAILABLE, Boolean.toString(available)); | ||
| 97 | + add(AVAILABLE_IID, iconId); | ||
| 98 | + add(TYPE_IID, getTypeIconId(d)); | ||
| 99 | + add(ROLE, service.getRole(d.id()).toString()); | ||
| 100 | + add(MFR, d.manufacturer()); | ||
| 101 | + add(HW, d.hwVersion()); | ||
| 102 | + add(SW, d.swVersion()); | ||
| 103 | + add(SERIAL, d.serialNumber()); | ||
| 104 | + add(PROTOCOL, d.annotations().value(PROTOCOL)); | ||
| 105 | + add(CHASSISID, d.chassisId().toString()); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + private String getTypeIconId(Device d) { | ||
| 109 | + return DEV_ICON_PREFIX + d.type().toString(); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + @Override | ||
| 113 | + protected String[] columnIds() { | ||
| 114 | + return COL_IDS; | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + | ||
| 73 | } | 118 | } | ... | ... |
| 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 | +package org.onosproject.ui.impl; | ||
| 17 | + | ||
| 18 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 20 | +import com.google.common.collect.ImmutableSet; | ||
| 21 | +import org.onosproject.net.Device; | ||
| 22 | +import org.onosproject.net.device.DeviceService; | ||
| 23 | + | ||
| 24 | +import java.util.ArrayList; | ||
| 25 | +import java.util.Arrays; | ||
| 26 | +import java.util.List; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * Message handler for host view related messages. | ||
| 30 | + */ | ||
| 31 | +public class HostViewMessageHandler extends AbstractTabularViewMessageHandler { | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * Creates a new message handler for the host messages. | ||
| 35 | + */ | ||
| 36 | + protected HostViewMessageHandler() { | ||
| 37 | + super(ImmutableSet.of("hostDataRequest")); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + @Override | ||
| 41 | + public void process(ObjectNode message) { | ||
| 42 | + ObjectNode payload = payload(message); | ||
| 43 | + String sortCol = string(payload, "sortCol", "id"); | ||
| 44 | + String sortDir = string(payload, "sortDir", "asc"); | ||
| 45 | + | ||
| 46 | + DeviceService service = get(DeviceService.class); | ||
| 47 | + TableRow[] rows = generateTableRows(service); | ||
| 48 | + RowComparator rc = new RowComparator(sortCol, RowComparator.direction(sortDir)); | ||
| 49 | + Arrays.sort(rows, rc); | ||
| 50 | + ArrayNode devices = generateArrayNode(rows); | ||
| 51 | + ObjectNode rootNode = mapper.createObjectNode(); | ||
| 52 | + rootNode.set("devices", devices); | ||
| 53 | + | ||
| 54 | + connection().sendMessage("hostDataResponse", 0, rootNode); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + private TableRow[] generateTableRows(DeviceService service) { | ||
| 58 | + List<TableRow> list = new ArrayList<>(); | ||
| 59 | + for (Device dev : service.getDevices()) { | ||
| 60 | + list.add(new HostTableRow(service, dev)); | ||
| 61 | + } | ||
| 62 | + return list.toArray(new TableRow[list.size()]); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * TableRow implementation for {@link Device devices}. | ||
| 67 | + */ | ||
| 68 | + private static class HostTableRow extends AbstractTableRow { | ||
| 69 | + | ||
| 70 | + private static final String ID = "id"; | ||
| 71 | + private static final String AVAILABLE = "available"; | ||
| 72 | + private static final String AVAILABLE_IID = "_iconid_available"; | ||
| 73 | + private static final String TYPE_IID = "_iconid_type"; | ||
| 74 | + private static final String DEV_ICON_PREFIX = "devIcon_"; | ||
| 75 | + private static final String ROLE = "role"; | ||
| 76 | + private static final String MFR = "mfr"; | ||
| 77 | + private static final String HW = "hw"; | ||
| 78 | + private static final String SW = "sw"; | ||
| 79 | + private static final String SERIAL = "serial"; | ||
| 80 | + private static final String PROTOCOL = "protocol"; | ||
| 81 | + private static final String CHASSISID = "chassisid"; | ||
| 82 | + | ||
| 83 | + private static final String[] COL_IDS = { | ||
| 84 | + ID, AVAILABLE, AVAILABLE_IID, TYPE_IID, ROLE, | ||
| 85 | + MFR, HW, SW, SERIAL, PROTOCOL, CHASSISID | ||
| 86 | + }; | ||
| 87 | + | ||
| 88 | + private static final String ICON_ID_ONLINE = "deviceOnline"; | ||
| 89 | + private static final String ICON_ID_OFFLINE = "deviceOffline"; | ||
| 90 | + | ||
| 91 | + public HostTableRow(DeviceService service, Device d) { | ||
| 92 | + boolean available = service.isAvailable(d.id()); | ||
| 93 | + String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE; | ||
| 94 | + | ||
| 95 | + add(ID, d.id().toString()); | ||
| 96 | + add(AVAILABLE, Boolean.toString(available)); | ||
| 97 | + add(AVAILABLE_IID, iconId); | ||
| 98 | + add(TYPE_IID, getTypeIconId(d)); | ||
| 99 | + add(ROLE, service.getRole(d.id()).toString()); | ||
| 100 | + add(MFR, d.manufacturer()); | ||
| 101 | + add(HW, d.hwVersion()); | ||
| 102 | + add(SW, d.swVersion()); | ||
| 103 | + add(SERIAL, d.serialNumber()); | ||
| 104 | + add(PROTOCOL, d.annotations().value(PROTOCOL)); | ||
| 105 | + add(CHASSISID, d.chassisId().toString()); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + private String getTypeIconId(Device d) { | ||
| 109 | + return DEV_ICON_PREFIX + d.type().toString(); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + @Override | ||
| 113 | + protected String[] columnIds() { | ||
| 114 | + return COL_IDS; | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | +} |
| ... | @@ -566,6 +566,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -566,6 +566,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 566 | 566 | ||
| 567 | // Adds all internal listeners. | 567 | // Adds all internal listeners. |
| 568 | private void addListeners() { | 568 | private void addListeners() { |
| 569 | + listenersRemoved = false; | ||
| 569 | clusterService.addListener(clusterListener); | 570 | clusterService.addListener(clusterListener); |
| 570 | mastershipService.addListener(mastershipListener); | 571 | mastershipService.addListener(mastershipListener); |
| 571 | deviceService.addListener(deviceListener); | 572 | deviceService.addListener(deviceListener); | ... | ... |
| ... | @@ -58,10 +58,13 @@ public class UiExtensionManager implements UiExtensionService { | ... | @@ -58,10 +58,13 @@ public class UiExtensionManager implements UiExtensionService { |
| 58 | private static UiExtension createCoreExtension() { | 58 | private static UiExtension createCoreExtension() { |
| 59 | List<UiView> coreViews = of(new UiView("topo", "Topology View"), | 59 | List<UiView> coreViews = of(new UiView("topo", "Topology View"), |
| 60 | new UiView("device", "Devices"), | 60 | new UiView("device", "Devices"), |
| 61 | + new UiView("host", "Hosts"), | ||
| 61 | new UiView("sample", "Sample")); | 62 | new UiView("sample", "Sample")); |
| 62 | UiMessageHandlerFactory messageHandlerFactory = | 63 | UiMessageHandlerFactory messageHandlerFactory = |
| 63 | () -> ImmutableList.of( | 64 | () -> ImmutableList.of( |
| 64 | - new TopologyViewMessageHandler() | 65 | + new TopologyViewMessageHandler(), |
| 66 | + new DeviceViewMessageHandler(), | ||
| 67 | + new HostViewMessageHandler() | ||
| 65 | ); | 68 | ); |
| 66 | return new UiExtension(coreViews, messageHandlerFactory, "core", | 69 | return new UiExtension(coreViews, messageHandlerFactory, "core", |
| 67 | UiExtensionManager.class.getClassLoader()); | 70 | UiExtensionManager.class.getClassLoader()); | ... | ... |
| 1 | <link rel="stylesheet" href="app/view/sample/sample.css"> | 1 | <link rel="stylesheet" href="app/view/sample/sample.css"> |
| 2 | <link rel="stylesheet" href="app/view/topo/topo.css"> | 2 | <link rel="stylesheet" href="app/view/topo/topo.css"> |
| 3 | <link rel="stylesheet" href="app/view/device/device.css"> | 3 | <link rel="stylesheet" href="app/view/device/device.css"> |
| 4 | +<link rel="stylesheet" href="app/view/host/host.css"> | ... | ... |
| ... | @@ -12,4 +12,5 @@ | ... | @@ -12,4 +12,5 @@ |
| 12 | <script src="app/view/topo/topoTraffic.js"></script> | 12 | <script src="app/view/topo/topoTraffic.js"></script> |
| 13 | <script src="app/view/topo/topoToolbar.js"></script> | 13 | <script src="app/view/topo/topoToolbar.js"></script> |
| 14 | <script src="app/view/device/device.js"></script> | 14 | <script src="app/view/device/device.js"></script> |
| 15 | +<script src="app/view/host/host.js"></script> | ||
| 15 | <script src="app/view/sample/sample.js"></script> | 16 | <script src="app/view/sample/sample.js"></script> | ... | ... |
| ... | @@ -139,7 +139,6 @@ | ... | @@ -139,7 +139,6 @@ |
| 139 | <param-name>com.sun.jersey.config.property.classnames</param-name> | 139 | <param-name>com.sun.jersey.config.property.classnames</param-name> |
| 140 | <param-value> | 140 | <param-value> |
| 141 | org.onosproject.ui.impl.TopologyResource, | 141 | org.onosproject.ui.impl.TopologyResource, |
| 142 | - org.onosproject.ui.impl.DeviceGuiResource | ||
| 143 | </param-value> | 142 | </param-value> |
| 144 | </init-param> | 143 | </init-param> |
| 145 | <load-on-startup>1</load-on-startup> | 144 | <load-on-startup>1</load-on-startup> | ... | ... |
| ... | @@ -23,30 +23,39 @@ | ... | @@ -23,30 +23,39 @@ |
| 23 | 23 | ||
| 24 | angular.module('ovDevice', []) | 24 | angular.module('ovDevice', []) |
| 25 | .controller('OvDeviceCtrl', | 25 | .controller('OvDeviceCtrl', |
| 26 | - ['$log', '$scope', '$location', 'RestService', 'VeilService', | 26 | + ['$log', '$scope', '$location', 'WebSocketService', |
| 27 | 27 | ||
| 28 | - function ($log, $scope, $location, rs, vs) { | 28 | + function ($log, $scope, $location, wss) { |
| 29 | var self = this; | 29 | var self = this; |
| 30 | self.deviceData = []; | 30 | self.deviceData = []; |
| 31 | 31 | ||
| 32 | + $scope.responseCallback = function(data) { | ||
| 33 | + self.deviceData = data.devices; | ||
| 34 | + $scope.$apply(); | ||
| 35 | + }; | ||
| 36 | + | ||
| 32 | $scope.sortCallback = function (urlSuffix) { | 37 | $scope.sortCallback = function (urlSuffix) { |
| 38 | + // FIXME: fix hardcoded sort params | ||
| 33 | if (!urlSuffix) { | 39 | if (!urlSuffix) { |
| 34 | urlSuffix = ''; | 40 | urlSuffix = ''; |
| 35 | } | 41 | } |
| 36 | - var url = 'device' + urlSuffix; | 42 | + var payload = { sortCol: 'id', sortDir: 'asc' }; |
| 37 | - rs.get(url, function (data) { | 43 | + wss.sendEvent('deviceDataRequest', payload); |
| 38 | - self.deviceData = data.devices; | ||
| 39 | - }, function (errMsg) { | ||
| 40 | - vs.lostServer('OvDeviceCtrl', errMsg); | ||
| 41 | - }); | ||
| 42 | }; | 44 | }; |
| 43 | - $scope.sortCallback(); | 45 | + |
| 46 | + var handlers = { | ||
| 47 | + deviceDataResponse: $scope.responseCallback | ||
| 48 | + }; | ||
| 49 | + wss.bindHandlers(handlers); | ||
| 44 | 50 | ||
| 45 | // Cleanup on destroyed scope | 51 | // Cleanup on destroyed scope |
| 46 | $scope.$on('$destroy', function () { | 52 | $scope.$on('$destroy', function () { |
| 47 | - | 53 | + wss.unbindHandlers(handlers); |
| 48 | }); | 54 | }); |
| 49 | 55 | ||
| 50 | $log.log('OvDeviceCtrl has been created'); | 56 | $log.log('OvDeviceCtrl has been created'); |
| 57 | + | ||
| 58 | + $scope.sortCallback(); | ||
| 59 | + | ||
| 51 | }]); | 60 | }]); |
| 52 | }()); | 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 | +/* | ||
| 18 | + ONOS GUI -- Device View -- CSS file | ||
| 19 | + */ | ||
| 20 | + | ||
| 21 | +#ov-device th { | ||
| 22 | + cursor: pointer; | ||
| 23 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<!-- Host partial HTML --> | ||
| 2 | +<div id="ov-host"> | ||
| 3 | + <h2>Hosts ({{ctrl.hostData.length}} total)</h2> | ||
| 4 | + <table class="summary-list" | ||
| 5 | + onos-fixed-header | ||
| 6 | + onos-sortable-header | ||
| 7 | + sort-callback="sortCallback(urlSuffix)"> | ||
| 8 | + <thead> | ||
| 9 | + <tr> | ||
| 10 | + <th colId="available"></th> | ||
| 11 | + <th colId="type"></th> | ||
| 12 | + <th colId="id" sortable>Host ID </th> | ||
| 13 | + <th colId="mfr" sortable>Vendor </th> | ||
| 14 | + <th colId="hw" sortable>H/W Version </th> | ||
| 15 | + <th colId="sw" sortable>S/W Version </th> | ||
| 16 | + <th colId="chassisid" sortable>Chassis ID </th> | ||
| 17 | + <th colId="serial" sortable>Serial # </th> | ||
| 18 | + <th colId="protocol" sortable>Protocol </th> | ||
| 19 | + </tr> | ||
| 20 | + </thead> | ||
| 21 | + | ||
| 22 | + <tbody> | ||
| 23 | + <tr ng-repeat="host in ctrl.hostData" | ||
| 24 | + ng-repeat-done> | ||
| 25 | + <td class="table-icon"> | ||
| 26 | + <div icon icon-id="{{host._iconid_available}}"></div> | ||
| 27 | + </td> | ||
| 28 | + <td class="table-icon"> | ||
| 29 | + <div icon icon-id="{{host._iconid_type}}"></div> | ||
| 30 | + </td> | ||
| 31 | + <td>{{host.id}}</td> | ||
| 32 | + <td>{{host.mfr}}</td> | ||
| 33 | + <td>{{host.hw}}</td> | ||
| 34 | + <td>{{host.sw}}</td> | ||
| 35 | + <td>{{host.chassisid}}</td> | ||
| 36 | + <td>{{host.serial}}</td> | ||
| 37 | + <td>{{host.protocol}}</td> | ||
| 38 | + </tr> | ||
| 39 | + </tbody> | ||
| 40 | + </table> | ||
| 41 | + | ||
| 42 | +</div> |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +/* | ||
| 18 | + ONOS GUI -- Host View Module | ||
| 19 | + */ | ||
| 20 | + | ||
| 21 | +(function () { | ||
| 22 | + 'use strict'; | ||
| 23 | + | ||
| 24 | + angular.module('ovHost', []) | ||
| 25 | + .controller('OvHostCtrl', | ||
| 26 | + ['$log', '$scope', '$location', 'WebSocketService', | ||
| 27 | + | ||
| 28 | + function ($log, $scope, $location, wss) { | ||
| 29 | + var self = this; | ||
| 30 | + self.hostData = []; | ||
| 31 | + | ||
| 32 | + $scope.responseCallback = function(data) { | ||
| 33 | + self.hostData = data.devices; | ||
| 34 | + $scope.$apply(); | ||
| 35 | + }; | ||
| 36 | + | ||
| 37 | + $scope.sortCallback = function (urlSuffix) { | ||
| 38 | + // FIXME: fix hardcoded sort params | ||
| 39 | + if (!urlSuffix) { | ||
| 40 | + urlSuffix = ''; | ||
| 41 | + } | ||
| 42 | + var payload = { sortCol: 'id', sortDir: 'asc' }; | ||
| 43 | + wss.sendEvent('hostDataRequest', payload); | ||
| 44 | + }; | ||
| 45 | + | ||
| 46 | + var handlers = { | ||
| 47 | + hostDataResponse: $scope.responseCallback | ||
| 48 | + }; | ||
| 49 | + wss.bindHandlers(handlers); | ||
| 50 | + | ||
| 51 | + // Cleanup on destroyed scope | ||
| 52 | + $scope.$on('$destroy', function () { | ||
| 53 | + wss.unbindHandlers(handlers); | ||
| 54 | + }); | ||
| 55 | + | ||
| 56 | + $log.log('OvHostCtrl has been created'); | ||
| 57 | + | ||
| 58 | + $scope.sortCallback(); | ||
| 59 | + }]); | ||
| 60 | +}()); |
| ... | @@ -100,6 +100,7 @@ | ... | @@ -100,6 +100,7 @@ |
| 100 | <script src="app/view/topo/topoTraffic.js"></script> | 100 | <script src="app/view/topo/topoTraffic.js"></script> |
| 101 | <script src="app/view/topo/topoToolbar.js"></script> | 101 | <script src="app/view/topo/topoToolbar.js"></script> |
| 102 | <script src="app/view/device/device.js"></script> | 102 | <script src="app/view/device/device.js"></script> |
| 103 | + <script src="app/view/host/host.js"></script> | ||
| 103 | <script src="app/view/sample/sample.js"></script> | 104 | <script src="app/view/sample/sample.js"></script> |
| 104 | <!-- {INJECTED-JAVASCRIPT-END} --> | 105 | <!-- {INJECTED-JAVASCRIPT-END} --> |
| 105 | 106 | ||
| ... | @@ -108,6 +109,7 @@ | ... | @@ -108,6 +109,7 @@ |
| 108 | <!-- {INJECTED-STYLESHEETS-START} --> | 109 | <!-- {INJECTED-STYLESHEETS-START} --> |
| 109 | <link rel="stylesheet" href="app/view/topo/topo.css"> | 110 | <link rel="stylesheet" href="app/view/topo/topo.css"> |
| 110 | <link rel="stylesheet" href="app/view/device/device.css"> | 111 | <link rel="stylesheet" href="app/view/device/device.css"> |
| 112 | + <link rel="stylesheet" href="app/view/host/host.css"> | ||
| 111 | <link rel="stylesheet" href="app/view/sample/sample.css"> | 113 | <link rel="stylesheet" href="app/view/sample/sample.css"> |
| 112 | <!-- {INJECTED-STYLESHEETS-END} --> | 114 | <!-- {INJECTED-STYLESHEETS-END} --> |
| 113 | 115 | ... | ... |
-
Please register or login to post a comment