ONOS-3387 Adding ability for network configurations to be validated before being accepted into the system.

Change-Id: I26a7e2adb20318cf17a35081ff753b3448105e31
diff --git a/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java b/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
index 3e73d8f..ca8eea3 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
@@ -60,6 +60,7 @@
 import java.util.Objects;
 import java.util.Set;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static org.onosproject.net.config.NetworkConfigEvent.Type.*;
 
 /**
@@ -71,10 +72,12 @@
         extends AbstractStore<NetworkConfigEvent, NetworkConfigStoreDelegate>
         implements NetworkConfigStore {
 
-    private static final int MAX_BACKOFF = 10;
-
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    private static final int MAX_BACKOFF = 10;
+    private static final String INVALID_CONFIG_JSON =
+            "JSON node does not contain valid configuration";
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected StorageService storageService;
 
@@ -187,8 +190,17 @@
 
     @Override
     public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, JsonNode json) {
-        return createConfig(subject, configClass,
-                            configs.putAndGet(key(subject, configClass), json).value());
+        // Create the configuration and validate it.
+        C config = createConfig(subject, configClass, json);
+        checkArgument(config.isValid(), INVALID_CONFIG_JSON);
+
+        // Insert the validated configuration and get it back.
+        Versioned<JsonNode> versioned = configs.putAndGet(key(subject, configClass), json);
+
+        // Re-create the config if for some reason what we attempted to put
+        // was supplanted by someone else already.
+        return versioned.value() == json ? config :
+                createConfig(subject, configClass, versioned.value());
     }
 
     @Override