Thomas Vachuska
Committed by Gerrit Code Review

Adding protection against UI extension failures crashing the whole UI.

Fixed NPE for null devices when displaying details.

Change-Id: I0053939807ea2493e125c7a1fd58606e4c4d3e02
......@@ -15,6 +15,7 @@
*/
package org.onosproject.ui;
import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -44,6 +45,7 @@ public final class UiExtension {
private final UiMessageHandlerFactory messageHandlerFactory;
private final UiTopoOverlayFactory topoOverlayFactory;
private boolean isValid = true;
// private constructor - only the builder calls this
private UiExtension(ClassLoader cl, String path, List<UiView> views,
......@@ -81,7 +83,7 @@ public final class UiExtension {
* @return contributed view descriptors
*/
public List<UiView> views() {
return views;
return isValid ? views : ImmutableList.of();
}
/**
......@@ -118,6 +120,7 @@ public final class UiExtension {
private InputStream getStream(String path) {
InputStream stream = classLoader.getResourceAsStream(path);
if (stream == null) {
isValid = false;
log.warn("Unable to find resource {}", path);
}
return stream;
......
......@@ -18,6 +18,7 @@ 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.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ConnectPoint;
......@@ -86,6 +87,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler {
private static final String NAME = "name";
private static final String WARN = "warn";
private static final String NONE = "none";
private static final String[] COL_IDS = {
AVAILABLE, AVAILABLE_IID, TYPE_IID,
......@@ -178,6 +180,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler {
MastershipService ms = get(MastershipService.class);
Device device = service.getDevice(deviceId);
ObjectNode data = objectNode();
NodeId masterFor = ms.getMasterFor(deviceId);
data.put(ID, deviceId.toString());
data.put(NAME, deviceName(device));
......@@ -188,7 +191,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler {
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(MASTER_ID, masterFor != null ? masterFor.toString() : NONE);
data.put(PROTOCOL, deviceProtocol(device));
ArrayNode ports = arrayNode();
......
......@@ -186,12 +186,16 @@ public class UiWebSocket
UiMessageHandlerFactory factory = ext.messageHandlerFactory();
if (factory != null) {
factory.newHandlers().forEach(handler -> {
handler.init(this, directory);
handler.messageTypes().forEach(type -> handlers.put(type, handler));
// need to inject the overlay cache into topology message handler
if (handler instanceof TopologyViewMessageHandler) {
((TopologyViewMessageHandler) handler).setOverlayCache(overlayCache);
try {
handler.init(this, directory);
handler.messageTypes().forEach(type -> handlers.put(type, handler));
// need to inject the overlay cache into topology message handler
if (handler instanceof TopologyViewMessageHandler) {
((TopologyViewMessageHandler) handler).setOverlayCache(overlayCache);
}
} catch (Exception e) {
log.warn("Unable to setup handler {} due to", handler, e);
}
});
}
......