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 @@ ...@@ -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 }
......