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
Showing
3 changed files
with
18 additions
and
8 deletions
| ... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.ui; | 16 | package org.onosproject.ui; |
| 17 | 17 | ||
| 18 | +import com.google.common.collect.ImmutableList; | ||
| 18 | import org.slf4j.Logger; | 19 | import org.slf4j.Logger; |
| 19 | import org.slf4j.LoggerFactory; | 20 | import org.slf4j.LoggerFactory; |
| 20 | 21 | ||
| ... | @@ -44,6 +45,7 @@ public final class UiExtension { | ... | @@ -44,6 +45,7 @@ public final class UiExtension { |
| 44 | private final UiMessageHandlerFactory messageHandlerFactory; | 45 | private final UiMessageHandlerFactory messageHandlerFactory; |
| 45 | private final UiTopoOverlayFactory topoOverlayFactory; | 46 | private final UiTopoOverlayFactory topoOverlayFactory; |
| 46 | 47 | ||
| 48 | + private boolean isValid = true; | ||
| 47 | 49 | ||
| 48 | // private constructor - only the builder calls this | 50 | // private constructor - only the builder calls this |
| 49 | private UiExtension(ClassLoader cl, String path, List<UiView> views, | 51 | private UiExtension(ClassLoader cl, String path, List<UiView> views, |
| ... | @@ -81,7 +83,7 @@ public final class UiExtension { | ... | @@ -81,7 +83,7 @@ public final class UiExtension { |
| 81 | * @return contributed view descriptors | 83 | * @return contributed view descriptors |
| 82 | */ | 84 | */ |
| 83 | public List<UiView> views() { | 85 | public List<UiView> views() { |
| 84 | - return views; | 86 | + return isValid ? views : ImmutableList.of(); |
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | /** | 89 | /** |
| ... | @@ -118,6 +120,7 @@ public final class UiExtension { | ... | @@ -118,6 +120,7 @@ public final class UiExtension { |
| 118 | private InputStream getStream(String path) { | 120 | private InputStream getStream(String path) { |
| 119 | InputStream stream = classLoader.getResourceAsStream(path); | 121 | InputStream stream = classLoader.getResourceAsStream(path); |
| 120 | if (stream == null) { | 122 | if (stream == null) { |
| 123 | + isValid = false; | ||
| 121 | log.warn("Unable to find resource {}", path); | 124 | log.warn("Unable to find resource {}", path); |
| 122 | } | 125 | } |
| 123 | return stream; | 126 | return stream; | ... | ... |
| ... | @@ -18,6 +18,7 @@ package org.onosproject.ui.impl; | ... | @@ -18,6 +18,7 @@ package org.onosproject.ui.impl; |
| 18 | import com.fasterxml.jackson.databind.node.ArrayNode; | 18 | import com.fasterxml.jackson.databind.node.ArrayNode; |
| 19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
| 20 | import com.google.common.collect.ImmutableSet; | 20 | import com.google.common.collect.ImmutableSet; |
| 21 | +import org.onosproject.cluster.NodeId; | ||
| 21 | import org.onosproject.mastership.MastershipService; | 22 | import org.onosproject.mastership.MastershipService; |
| 22 | import org.onosproject.net.AnnotationKeys; | 23 | import org.onosproject.net.AnnotationKeys; |
| 23 | import org.onosproject.net.ConnectPoint; | 24 | import org.onosproject.net.ConnectPoint; |
| ... | @@ -86,6 +87,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler { | ... | @@ -86,6 +87,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler { |
| 86 | private static final String NAME = "name"; | 87 | private static final String NAME = "name"; |
| 87 | private static final String WARN = "warn"; | 88 | private static final String WARN = "warn"; |
| 88 | 89 | ||
| 90 | + private static final String NONE = "none"; | ||
| 89 | 91 | ||
| 90 | private static final String[] COL_IDS = { | 92 | private static final String[] COL_IDS = { |
| 91 | AVAILABLE, AVAILABLE_IID, TYPE_IID, | 93 | AVAILABLE, AVAILABLE_IID, TYPE_IID, |
| ... | @@ -178,6 +180,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler { | ... | @@ -178,6 +180,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler { |
| 178 | MastershipService ms = get(MastershipService.class); | 180 | MastershipService ms = get(MastershipService.class); |
| 179 | Device device = service.getDevice(deviceId); | 181 | Device device = service.getDevice(deviceId); |
| 180 | ObjectNode data = objectNode(); | 182 | ObjectNode data = objectNode(); |
| 183 | + NodeId masterFor = ms.getMasterFor(deviceId); | ||
| 181 | 184 | ||
| 182 | data.put(ID, deviceId.toString()); | 185 | data.put(ID, deviceId.toString()); |
| 183 | data.put(NAME, deviceName(device)); | 186 | data.put(NAME, deviceName(device)); |
| ... | @@ -188,7 +191,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler { | ... | @@ -188,7 +191,7 @@ public class DeviceViewMessageHandler extends UiMessageHandler { |
| 188 | data.put(SW, device.swVersion()); | 191 | data.put(SW, device.swVersion()); |
| 189 | data.put(SERIAL, device.serialNumber()); | 192 | data.put(SERIAL, device.serialNumber()); |
| 190 | data.put(CHASSIS_ID, device.chassisId().toString()); | 193 | data.put(CHASSIS_ID, device.chassisId().toString()); |
| 191 | - data.put(MASTER_ID, ms.getMasterFor(deviceId).toString()); | 194 | + data.put(MASTER_ID, masterFor != null ? masterFor.toString() : NONE); |
| 192 | data.put(PROTOCOL, deviceProtocol(device)); | 195 | data.put(PROTOCOL, deviceProtocol(device)); |
| 193 | 196 | ||
| 194 | ArrayNode ports = arrayNode(); | 197 | ArrayNode ports = arrayNode(); | ... | ... |
| ... | @@ -186,12 +186,16 @@ public class UiWebSocket | ... | @@ -186,12 +186,16 @@ public class UiWebSocket |
| 186 | UiMessageHandlerFactory factory = ext.messageHandlerFactory(); | 186 | UiMessageHandlerFactory factory = ext.messageHandlerFactory(); |
| 187 | if (factory != null) { | 187 | if (factory != null) { |
| 188 | factory.newHandlers().forEach(handler -> { | 188 | factory.newHandlers().forEach(handler -> { |
| 189 | - handler.init(this, directory); | 189 | + try { |
| 190 | - handler.messageTypes().forEach(type -> handlers.put(type, handler)); | 190 | + handler.init(this, directory); |
| 191 | - | 191 | + handler.messageTypes().forEach(type -> handlers.put(type, handler)); |
| 192 | - // need to inject the overlay cache into topology message handler | 192 | + |
| 193 | - if (handler instanceof TopologyViewMessageHandler) { | 193 | + // need to inject the overlay cache into topology message handler |
| 194 | - ((TopologyViewMessageHandler) handler).setOverlayCache(overlayCache); | 194 | + if (handler instanceof TopologyViewMessageHandler) { |
| 195 | + ((TopologyViewMessageHandler) handler).setOverlayCache(overlayCache); | ||
| 196 | + } | ||
| 197 | + } catch (Exception e) { | ||
| 198 | + log.warn("Unable to setup handler {} due to", handler, e); | ||
| 195 | } | 199 | } |
| 196 | }); | 200 | }); |
| 197 | } | 201 | } | ... | ... |
-
Please register or login to post a comment