Implementing net config subsystem and revising its interfaces.

Added a few basic configs for device, host and links.

Added initial REST API.

Added CLI.

Tests remain to be added.

Change-Id: Ic7bba4b5ad7d553c51d69f6459b3bff146970323
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigService.java
index dd88a16..fb0c48f 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigService.java
@@ -15,26 +15,59 @@
  */
 package org.onosproject.incubator.net.config;
 
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.annotations.Beta;
 
 import java.util.Set;
 
 /**
  * Service for tracking network configurations which specify how the discovered
- * network information should be interpreted and how the network should be
- * configured.
+ * network information should be interpreted and how the core or applications
+ * should act on or configure the network.
  */
 @Beta
 public interface NetworkConfigService {
 
     /**
+     * Returns the set of subject classes for which configuration may be
+     * available.
+     *
+     * @return set of subject classes
+     */
+    Set<Class> getSubjectClasses();
+
+    /**
+     * Returns the subject factory with the specified key.
+     *
+     * @param subjectKey subject class key
+     * @return subject class
+     */
+    SubjectFactory getSubjectFactory(String subjectKey);
+
+    /**
+     * Returns the subject factory for the specified class.
+     *
+     * @param subjectClass subject class
+     * @return subject class key
+     */
+    SubjectFactory getSubjectFactory(Class subjectClass);
+
+    /**
+     * Returns the configuration class with the specified key.
+     *
+     * @param configKey subject class name
+     * @return subject class
+     */
+    Class<? extends Config> getConfigClass(String configKey);
+
+    /**
      * Returns the set of subjects for which some configuration is available.
      *
      * @param subjectClass subject class
-     * @param <T> type of subject
+     * @param <S>          type of subject
      * @return set of configured subjects
      */
-    <T> Set<T> getSubjects(Class<T> subjectClass);
+    <S> Set<S> getSubjects(Class<S> subjectClass);
 
     /**
      * Returns the set of subjects for which the specified configuration is
@@ -42,20 +75,20 @@
      *
      * @param subjectClass subject class
      * @param configClass  configuration class
-     * @param <T> type of subject
+     * @param <S>          type of subject
+     * @param <C>          type of configuration
      * @return set of configured subjects
      */
-    <T> Set<T> getSubjects(Class<T> subjectClass, Class<Config<T>> configClass);
-
+    <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass);
 
     /**
      * Returns all configurations for the specified subject.
      *
      * @param subject configuration subject
-     * @param <T> type of subject
+     * @param <S>     type of subject
      * @return set of configurations
      */
-    <T> Set<Config<T>> getConfigs(T subject);
+    <S> Set<? extends Config<S>> getConfigs(S subject);
 
     /**
      * Returns the configuration for the specified subject and configuration
@@ -63,9 +96,61 @@
      *
      * @param subject     configuration subject
      * @param configClass configuration class
-     * @param <T> type of subject
+     * @param <S>         type of subject
+     * @param <C>         type of configuration
      * @return configuration or null if one is not available
      */
-    <T> Config<T> getConfig(T subject, Class<Config<T>> configClass);
+    <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass);
 
+    /**
+     * Creates a new configuration for the specified subject and configuration
+     * class. If one already exists, it is simply returned.
+     *
+     * @param subject     configuration subject
+     * @param configClass configuration class
+     * @param <S>         type of subject
+     * @param <C>         type of configuration
+     * @return configuration or null if one is not available
+     */
+    <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass);
+
+    /**
+     * Applies configuration for the specified subject and configuration
+     * class using the raw JSON object. If configuration already exists, it
+     * will be updated.
+     *
+     * @param subject     configuration subject
+     * @param configClass configuration class
+     * @param json        raw JSON node containing the configuration data
+     * @param <S>         type of subject
+     * @param <C>         type of configuration
+     * @return configuration or null if one is not available
+     */
+    <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass,
+                                           ObjectNode json);
+
+    /**
+     * Clears any configuration for the specified subject and configuration
+     * class. If one does not exist, this call has no effect.
+     *
+     * @param subject     configuration subject
+     * @param configClass configuration class
+     * @param <S>         type of subject
+     * @param <C>         type of configuration
+     */
+    <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass);
+
+    /**
+     * Adds the specified network config listener.
+     *
+     * @param listener network config listener
+     */
+    void addListener(NetworkConfigListener listener);
+
+    /**
+     * Removes the specified network config listener.
+     *
+     * @param listener network config listener
+     */
+    void removeListener(NetworkConfigListener listener);
 }