ONOS-6517

NPE in network/configuration. Error in a config field shows error 
message 400 instead of 207.

Change-Id: I20aa8f7741262b46fbc56123e01524dcd165ff7c
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java
index 9d26891..77dd4ea 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/NetworkConfigWebResource.java
@@ -19,6 +19,7 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onosproject.net.config.Config;
+import org.onosproject.net.config.InvalidConfigException;
 import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.config.SubjectFactory;
 import org.onosproject.rest.AbstractWebResource;
@@ -69,6 +70,10 @@
                 + "' not found";
     }
 
+    private String subjectClassNotValidErrorString(String subjectClassKey) {
+        return "subjectClassKey '" + subjectClassKey + "' not found";
+    }
+
     /**
      * Gets entire network configuration base.
      *
@@ -149,9 +154,11 @@
                              @PathParam("configKey") String configKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
 
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotFoundErrorString(subjectClassKey));
         Object subject =
-                nullIsNotFound(service.getSubjectFactory(subjectClassKey)
-                                       .createSubject(subjectKey),
+                nullIsNotFound(subjectFactory.createSubject(subjectKey),
                                         subjectNotFoundErrorString(subjectClassKey, subjectKey));
 
         Class configClass =
@@ -200,8 +207,12 @@
         List<String> errorMsgs = new ArrayList<String>();
         root.fieldNames()
                 .forEachRemaining(sk -> {
-                    errorMsgs.addAll(consumeJson(service, (ObjectNode) root.path(sk),
-                                                 service.getSubjectFactory(sk)));
+                    if (service.getSubjectFactory(sk) == null)  {
+                        errorMsgs.add(subjectClassNotValidErrorString(sk));
+                    } else {
+                        errorMsgs.addAll(consumeJson(service, (ObjectNode) root.path(sk),
+                                service.getSubjectFactory(sk)));
+                    }
                 });
         if (!errorMsgs.isEmpty()) {
             return Response.status(MULTI_STATUS_RESPONE).entity(produceErrorJson(errorMsgs)).build();
@@ -225,7 +236,10 @@
                            InputStream request) throws IOException {
         NetworkConfigService service = get(NetworkConfigService.class);
         ObjectNode root = (ObjectNode) mapper().readTree(request);
-        List<String> errorMsgs = consumeJson(service, root, service.getSubjectFactory(subjectClassKey));
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotValidErrorString(subjectClassKey));
+        List<String> errorMsgs = consumeJson(service, root, subjectFactory);
         if (!errorMsgs.isEmpty()) {
             return Response.status(MULTI_STATUS_RESPONE).entity(produceErrorJson(errorMsgs)).build();
         }
@@ -250,8 +264,11 @@
                            InputStream request) throws IOException {
         NetworkConfigService service = get(NetworkConfigService.class);
         ObjectNode root = (ObjectNode) mapper().readTree(request);
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotValidErrorString(subjectClassKey));
         List<String> errorMsgs = consumeSubjectJson(service, root,
-                                 service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
+                subjectFactory.createSubject(subjectKey),
                                  subjectClassKey);
         if (!errorMsgs.isEmpty()) {
             return Response.status(MULTI_STATUS_RESPONE).entity(produceErrorJson(errorMsgs)).build();
@@ -279,8 +296,10 @@
                            InputStream request) throws IOException {
         NetworkConfigService service = get(NetworkConfigService.class);
         JsonNode root = mapper().readTree(request);
-        service.applyConfig(subjectClassKey,
-                            service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotValidErrorString(subjectClassKey));
+        service.applyConfig(subjectClassKey, subjectFactory.createSubject(subjectKey),
                             configKey, root);
         return Response.ok().build();
     }
@@ -306,6 +325,8 @@
                 service.applyConfig(subjectClassKey, subject, configKey, subjectNode.path(configKey));
             } catch (IllegalArgumentException e) {
                 errorMsgs.add("Error parsing config " + subjectClassKey + "/" + subject + "/" + configKey);
+            } catch (InvalidConfigException exception) {
+                errorMsgs.add(exception.getMessage());
             }
         });
         return errorMsgs;
@@ -343,7 +364,10 @@
     @SuppressWarnings("unchecked")
     public Response delete(@PathParam("subjectClassKey") String subjectClassKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
-        service.getSubjects(service.getSubjectFactory(subjectClassKey).subjectClass())
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotValidErrorString(subjectClassKey));
+        service.getSubjects(subjectFactory.subjectClass())
                 .forEach(subject -> service.removeConfig(subject));
         return Response.noContent().build();
     }
@@ -361,7 +385,10 @@
     public Response delete(@PathParam("subjectClassKey") String subjectClassKey,
                            @PathParam("subjectKey") String subjectKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
-        service.removeConfig(service.getSubjectFactory(subjectClassKey).createSubject(subjectKey));
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotValidErrorString(subjectClassKey));
+        service.removeConfig(subjectFactory.createSubject(subjectKey));
         return Response.noContent().build();
     }
 
@@ -380,9 +407,11 @@
                            @PathParam("subjectKey") String subjectKey,
                            @PathParam("configKey") String configKey) {
         NetworkConfigService service = get(NetworkConfigService.class);
-        service.removeConfig(subjectClassKey,
-                             service.getSubjectFactory(subjectClassKey).createSubject(subjectKey),
-                            configKey);
+        SubjectFactory subjectFactory =
+                nullIsNotFound(service.getSubjectFactory(subjectClassKey),
+                        subjectClassNotValidErrorString(subjectClassKey));
+        service.removeConfig(subjectClassKey, subjectFactory.createSubject(subjectKey),
+                configKey);
         return Response.noContent().build();
     }