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/Config.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/Config.java
index dacef68..12f3114 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/config/Config.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/Config.java
@@ -23,41 +23,67 @@
/**
* Base abstraction of a configuration facade for a specific subject. Derived
- * classes should keep all state in the specified JSON tree.
+ * classes should keep all state in the specified JSON tree as that is the
+ * only state that will be distributed or persisted; this class is merely
+ * a facade for interacting with a particular facet of configuration on a
+ * given subject.
*
* @param <S> type of subject
*/
@Beta
public abstract class Config<S> {
- protected ObjectMapper mapper;
+ protected S subject;
+ protected String key;
protected ObjectNode node;
- private S subject;
- private ConfigApplyDelegate<S> delegate;
+ protected ObjectMapper mapper;
+ protected ConfigApplyDelegate delegate;
+
+ /**
+ * Initializes the configuration behaviour with necessary context.
+ *
+ * @param subject configuration subject
+ * @param key configuration key
+ * @param node JSON object node where configuration data is stored
+ * @param mapper JSON object mapper
+ * @param delegate delegate context
+ */
+ public void init(S subject, String key, ObjectNode node, ObjectMapper mapper,
+ ConfigApplyDelegate delegate) {
+ this.subject = checkNotNull(subject);
+ this.key = key;
+ this.node = checkNotNull(node);
+ this.mapper = checkNotNull(mapper);
+ this.delegate = checkNotNull(delegate);
+ }
/**
* Returns the specific subject to which this configuration pertains.
*
* @return configuration subject
*/
- S subject() {
+ public S subject() {
return subject;
}
/**
- * Initializes the configuration behaviour with necessary context.
+ * Returns the configuration key. This is primarily aimed for use in
+ * composite JSON trees in external representations and has no bearing on
+ * the internal behaviours.
*
- * @param subject configuration subject
- * @param node JSON object node where configuration data is stored
- * @param mapper JSON object mapper
- * @param delegate delegate context
+ * @return configuration key
*/
- public void init(S subject, ObjectNode node, ObjectMapper mapper,
- ConfigApplyDelegate<S> delegate) {
- this.subject = checkNotNull(subject);
- this.node = checkNotNull(node);
- this.mapper = checkNotNull(mapper);
- this.delegate = checkNotNull(delegate);
+ public String key() {
+ return key;
+ }
+
+ /**
+ * Returns the JSON node that contains the configuration data.
+ *
+ * @return JSON node backing the configuration
+ */
+ public ObjectNode node() {
+ return node;
}
/**
@@ -67,4 +93,142 @@
delegate.onApply(this);
}
+
+ // Miscellaneous helpers for interacting with JSON
+
+ /**
+ * Gets the specified property as a string.
+ *
+ * @param name property name
+ * @param defaultValue default value if property not set
+ * @return property value or default value
+ */
+ protected String get(String name, String defaultValue) {
+ return node.path(name).asText(defaultValue);
+ }
+
+ /**
+ * Sets the specified property as a string or clears it if null value given.
+ *
+ * @param name property name
+ * @param value new value or null to clear the property
+ * @return self
+ */
+ protected Config<S> setOrClear(String name, String value) {
+ if (value != null) {
+ node.put(name, value);
+ } else {
+ node.remove(name);
+ }
+ return this;
+ }
+
+ /**
+ * Gets the specified property as a boolean.
+ *
+ * @param name property name
+ * @param defaultValue default value if property not set
+ * @return property value or default value
+ */
+ protected boolean get(String name, boolean defaultValue) {
+ return node.path(name).asBoolean(defaultValue);
+ }
+
+ /**
+ * Sets the specified property as a boolean or clears it if null value given.
+ *
+ * @param name property name
+ * @param value new value or null to clear the property
+ * @return self
+ */
+ protected Config<S> setOrClear(String name, Boolean value) {
+ if (value != null) {
+ node.put(name, value.booleanValue());
+ } else {
+ node.remove(name);
+ }
+ return this;
+ }
+
+ /**
+ * Gets the specified property as a long.
+ *
+ * @param name property name
+ * @param defaultValue default value if property not set
+ * @return property value or default value
+ */
+ protected long get(String name, long defaultValue) {
+ return node.path(name).asLong(defaultValue);
+ }
+
+ /**
+ * Sets the specified property as a long or clears it if null value given.
+ *
+ * @param name property name
+ * @param value new value or null to clear the property
+ * @return self
+ */
+ protected Config<S> setOrClear(String name, Long value) {
+ if (value != null) {
+ node.put(name, value.longValue());
+ } else {
+ node.remove(name);
+ }
+ return this;
+ }
+
+ /**
+ * Gets the specified property as a double.
+ *
+ * @param name property name
+ * @param defaultValue default value if property not set
+ * @return property value or default value
+ */
+ protected double get(String name, double defaultValue) {
+ return node.path(name).asDouble(defaultValue);
+ }
+
+ /**
+ * Sets the specified property as a double or clears it if null value given.
+ *
+ * @param name property name
+ * @param value new value or null to clear the property
+ * @return self
+ */
+ protected Config<S> setOrClear(String name, Double value) {
+ if (value != null) {
+ node.put(name, value.doubleValue());
+ } else {
+ node.remove(name);
+ }
+ return this;
+ }
+
+ /**
+ * Gets the specified property as an enum.
+ *
+ * @param name property name
+ * @param defaultValue default value if property not set
+ * @param enumClass the enum class
+ * @return property value or default value
+ */
+ protected <E extends Enum<E>> E get(String name, E defaultValue, Class<E> enumClass) {
+ return Enum.valueOf(enumClass, node.path(name).asText(defaultValue.toString()));
+ }
+
+ /**
+ * Sets the specified property as a double or clears it if null value given.
+ *
+ * @param name property name
+ * @param value new value or null to clear the property
+ * @return self
+ */
+ protected <E extends Enum> Config<S> setOrClear(String name, E value) {
+ if (value != null) {
+ node.put(name, value.toString());
+ } else {
+ node.remove(name);
+ }
+ return this;
+ }
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigApplyDelegate.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigApplyDelegate.java
index 8bd6049..bcce280 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigApplyDelegate.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigApplyDelegate.java
@@ -21,13 +21,13 @@
* Delegate for notification when configuration changes have been applied.
*/
@Beta
-public interface ConfigApplyDelegate<S> {
+public interface ConfigApplyDelegate {
/**
* Processes changes applied to the specified configuration.
*
* @param config changed configuration
*/
- void onApply(Config<S> config);
+ void onApply(Config config);
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigFactory.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigFactory.java
index 37b51fd..673c7f3 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigFactory.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/ConfigFactory.java
@@ -21,24 +21,31 @@
/**
* Base abstract factory for creating configurations for the specified subject type.
*
- * @param <S> subject class
+ * @param <S> type of subject
+ * @param <C> type of configuration
*/
@Beta
-public abstract class ConfigFactory<S> {
+public abstract class ConfigFactory<S, C extends Config<S>> {
- private final Class<S> subjectClass;
- private final String key;
+ private final SubjectFactory<S> subjectFactory;
+ private final Class<C> configClass;
+ private final String configKey;
/**
* Creates a new configuration factory for the specified class of subjects
- * and bound to the given subject configuration key.
+ * capable of generating the configurations of the specified class. The
+ * subject and configuration class keys are used merely as keys for use in
+ * composite JSON trees.
*
- * @param subjectClass subject class
- * @param key subject configuration key
+ * @param subjectFactory subject factory
+ * @param configClass configuration class
+ * @param configKey configuration class key
*/
- protected ConfigFactory(Class<S> subjectClass, String key) {
- this.subjectClass = subjectClass;
- this.key = key;
+ protected ConfigFactory(SubjectFactory<S> subjectFactory,
+ Class<C> configClass, String configKey) {
+ this.subjectFactory = subjectFactory;
+ this.configClass = configClass;
+ this.configKey = configKey;
}
/**
@@ -46,17 +53,28 @@
*
* @return subject type
*/
- public Class<S> subjectClass() {
- return subjectClass;
+ public SubjectFactory<S> subjectFactory() {
+ return subjectFactory;
}
/**
- * Returns the key to which produced configurations should be bound.
+ * Returns the class of the configuration which this factory generates.
*
- * @return subject configuration key
+ * @return configuration type
*/
- public String key() {
- return key;
+ public Class<C> configClass() {
+ return configClass;
+ }
+
+ /**
+ * Returns the unique key (within subject class) of this configuration.
+ * This is primarily aimed for use in composite JSON trees in external
+ * representations and has no bearing on the internal behaviours.
+ *
+ * @return configuration key
+ */
+ public String configKey() {
+ return configKey;
}
/**
@@ -65,6 +83,6 @@
*
* @return new uninitialized configuration
*/
- public abstract Config<S> createConfig();
+ public abstract C createConfig();
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigEvent.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigEvent.java
new file mode 100644
index 0000000..e381f5a
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigEvent.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config;
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Describes network configuration event.
+ */
+public class NetworkConfigEvent extends AbstractEvent<NetworkConfigEvent.Type, Object> {
+
+ private final Class configClass;
+
+ /**
+ * Type of network configuration events.
+ */
+ public enum Type {
+ /**
+ * Signifies that network configuration was added.
+ */
+
+ CONFIG_ADDED,
+ /**
+ * Signifies that network configuration was updated.
+ */
+ CONFIG_UPDATED,
+
+ /**
+ * Signifies that network configuration was removed.
+ */
+ CONFIG_REMOVED
+ }
+
+ /**
+ * Creates an event of a given type and for the specified subject and the
+ * current time.
+ *
+ * @param type event type
+ * @param subject event subject
+ * @param configClass configuration class
+ */
+ public NetworkConfigEvent(Type type, Object subject, Class configClass) {
+ super(type, subject);
+ this.configClass = configClass;
+ }
+
+ /**
+ * Creates an event of a given type and for the specified subject and time.
+ *
+ * @param type device event type
+ * @param subject event subject
+ * @param configClass configuration class
+ * @param time occurrence time
+ */
+ public NetworkConfigEvent(Type type, Object subject, Class configClass, long time) {
+ super(type, subject, time);
+ this.configClass = configClass;
+ }
+
+ /**
+ * Returns the class of configuration that has been changed.
+ *
+ * @return configuration class
+ */
+ public Class configClass() {
+ return configClass;
+ }
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigListener.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigListener.java
new file mode 100644
index 0000000..38a0079
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of receiving network configuration related events.
+ */
+public interface NetworkConfigListener extends EventListener<NetworkConfigEvent> {
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigRegistry.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigRegistry.java
index 261e1bd..727d05a 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigRegistry.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigRegistry.java
@@ -20,7 +20,11 @@
import java.util.Set;
/**
- * Service for tracking network configuration factories.
+ * Service for tracking network configuration factories. It is the basis for
+ * extensibility to allow various core subsystems or apps to register their
+ * own configuration factories that permit use to inject additional meta
+ * information about how various parts of the network should be viewed and
+ * treated.
*/
@Beta
public interface NetworkConfigRegistry {
@@ -40,34 +44,32 @@
void unregisterConfigFactory(ConfigFactory configFactory);
/**
- * Returns set of configuration factories available for the specified
+ * Returns set of all registered configuration factories.
+ *
+ * @return set of config factories
+ */
+ Set<ConfigFactory> getConfigFactories();
+
+ /**
+ * Returns set of all configuration factories registered for the specified
* class of subject.
*
* @param subjectClass subject class
- * @param <T> type of subject
+ * @param <S> type of subject
+ * @param <C> type of configuration
* @return set of config factories
*/
- <T> Set<ConfigFactory<T>> getConfigFactories(Class<T> subjectClass);
+ <S, C extends Config<S>> Set<ConfigFactory<S, C>> getConfigFactories(Class<S> subjectClass);
/**
- * Returns the configuration type registered for the specified
- * subject type and key.
- *
- * @param subjectClass subject class
- * @param configKey configuration key
- * @param <T> type of subject
- * @return config factory
- */
- <T> ConfigFactory<T> getConfigFactory(Class<T> subjectClass, String configKey);
-
- /**
- * Returns the configuration type registered for the specified
- * configuration class.
+ * Returns the configuration factory that produces the specified class of
+ * configurations.
*
* @param configClass configuration class
- * @param <T> type of subject
+ * @param <S> type of subject
+ * @param <C> type of configuration
* @return config factory
*/
- <T> ConfigFactory<T> getConfigFactory(Class<Config<T>> configClass);
+ <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass);
}
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);
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStore.java
new file mode 100644
index 0000000..cd9e229
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStore.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.store.Store;
+
+import java.util.Set;
+
+/**
+ * Mechanism for distributing and storing network configuration information.
+ */
+public interface NetworkConfigStore extends Store<NetworkConfigEvent, NetworkConfigStoreDelegate> {
+
+ /**
+ * Adds a new configuration factory.
+ *
+ * @param configFactory configuration factory to add
+ */
+ void addConfigFactory(ConfigFactory configFactory);
+
+ /**
+ * Removes a configuration factory.
+ *
+ * @param configFactory configuration factory to remove
+ */
+ void removeConfigFactory(ConfigFactory configFactory);
+
+ /**
+ * Returns the configuration factory for the specified configuration class.
+ *
+ * @param configClass configuration class
+ * @param <S> type of subject
+ * @param <C> type of configuration
+ * @return configuration factory or null
+ */
+ <S, C extends Config<S>> ConfigFactory<S, C> getConfigFactory(Class<C> configClass);
+
+ /**
+ * Returns set of subjects of the specified class, which have some
+ * network configuration associated with them.
+ *
+ * @param subjectClass subject class
+ * @param <S> type of subject
+ * @return set of subject
+ */
+ <S> Set<S> getSubjects(Class<S> subjectClass);
+
+ /**
+ * Returns set of subjects of the specified class, which have the
+ * specified class of network configuration associated with them.
+ *
+ * @param subjectClass subject class
+ * @param configClass configuration class
+ * @param <S> type of subject
+ * @param <C> type of configuration
+ * @return set of subject
+ */
+ <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass);
+
+ /**
+ * Returns set of configuration classes available for the specified subject.
+ *
+ * @param subject configuration subject
+ * @param <S> type of subject
+ * @return set of configuration classes
+ */
+ <S> Set<Class<? extends Config<S>>> getConfigClasses(S subject);
+
+ /**
+ * Get the configuration of the given class and for the specified subject.
+ *
+ * @param subject configuration subject
+ * @param configClass configuration class
+ * @param <S> type of subject
+ * @param <C> type of configuration
+ * @return configuration object
+ */
+ <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass);
+
+ /**
+ * Creates a new configuration of the given class for the specified subject.
+ *
+ * @param subject configuration subject
+ * @param configClass configuration class
+ * @param <S> type of subject
+ * @param <C> type of configuration
+ * @return configuration object
+ */
+ <S, C extends Config<S>> C createConfig(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
+ */
+ <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass,
+ ObjectNode json);
+
+ /**
+ * Clears the configuration of the given class for the specified subject.
+ *
+ * @param subject configuration subject
+ * @param configClass configuration class
+ * @param <S> type of subject
+ * @param <C> type of configuration
+ */
+ <S, C extends Config<S>> void clearConfig(S subject, Class<C> configClass);
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStoreDelegate.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStoreDelegate.java
new file mode 100644
index 0000000..a77988d
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/NetworkConfigStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config;
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Network configuration store delegate abstraction.
+ */
+public interface NetworkConfigStoreDelegate extends StoreDelegate<NetworkConfigEvent> {
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/SubjectFactory.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/SubjectFactory.java
new file mode 100644
index 0000000..3f7e6dc
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/SubjectFactory.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config;
+
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Base abstract factory for creating configuration subjects from their
+ * string key image.
+ *
+ * @param <S> subject class
+ */
+@Beta
+public abstract class SubjectFactory<S> {
+
+ private final Class<S> subjectClass;
+ private final String subjectKey;
+
+ /**
+ * Creates a new configuration factory for the specified class of subjects
+ * capable of generating the configurations of the specified class. The
+ * subject and configuration class keys are used merely as keys for use in
+ * composite JSON trees.
+ *
+ * @param subjectClass subject class
+ * @param subjectKey subject class key
+ */
+ protected SubjectFactory(Class<S> subjectClass, String subjectKey) {
+ this.subjectClass = subjectClass;
+ this.subjectKey = subjectKey;
+ }
+
+ /**
+ * Returns the class of the subject to which this factory applies.
+ *
+ * @return subject type
+ */
+ public Class<S> subjectClass() {
+ return subjectClass;
+ }
+
+ /**
+ * Returns the unique key of this configuration subject class.
+ * This is primarily aimed for use in composite JSON trees in external
+ * representations and has no bearing on the internal behaviours.
+ *
+ * @return configuration key
+ */
+ public String subjectKey() {
+ return subjectKey;
+ }
+
+ /**
+ * Creates a configuration subject from its key image.
+ *
+ * @return configuration subject
+ */
+ public abstract S createSubject(String key);
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/AllowedEntityConfig.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/AllowedEntityConfig.java
new file mode 100644
index 0000000..6651ad4
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/AllowedEntityConfig.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config.basics;
+
+import org.onosproject.incubator.net.config.Config;
+
+/**
+ * Base abstraction for network entities for which admission into control
+ * domain can be selectively configured, e.g. devices, end-stations, links
+ */
+public abstract class AllowedEntityConfig<S> extends Config<S> {
+
+ private static final String ALLOWED = "allowed";
+
+ /**
+ * Indicates whether the element is allowed for admission into the control
+ * domain.
+ *
+ * @return true if element is allowed
+ */
+ public boolean isAllowed() {
+ return get(ALLOWED, true);
+ }
+
+ /**
+ * Specifies whether the element is to be allowed for admission into the
+ * control domain.
+ *
+ * @param isAllowed true to allow; false to forbid; null to clear
+ * @return self
+ */
+ public AllowedEntityConfig isAllowed(Boolean isAllowed) {
+ return (AllowedEntityConfig) setOrClear(ALLOWED, isAllowed);
+ }
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicDeviceConfig.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicDeviceConfig.java
new file mode 100644
index 0000000..c3eb099
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicDeviceConfig.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config.basics;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Basic configuration for network infrastructure devices.
+ */
+public class BasicDeviceConfig extends BasicElementConfig<DeviceId> {
+
+ public static final String TYPE = "type";
+ public static final String DRIVER = "driver";
+
+ /**
+ * Returns the device type.
+ *
+ * @return device type override
+ */
+ public Device.Type type() {
+ return get(TYPE, Device.Type.SWITCH, Device.Type.class);
+ }
+
+ /**
+ * Sets the device type.
+ *
+ * @param type device type override
+ * @return self
+ */
+ public BasicDeviceConfig type(Device.Type type) {
+ return (BasicDeviceConfig) setOrClear(TYPE, type);
+ }
+
+ /**
+ * Returns the device driver name.
+ *
+ * @return driver name of null if not set
+ */
+ public String driver() {
+ return get(DRIVER, subject.toString());
+ }
+
+ /**
+ * Sets the driver name.
+ *
+ * @param driverName new driver name; null to clear
+ * @return self
+ */
+ public BasicElementConfig driver(String driverName) {
+ return (BasicElementConfig) setOrClear(DRIVER, driverName);
+ }
+
+ // TODO: device port meta-data to be configured via BasicPortsConfig
+ // TODO: device credentials/keys
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicElementConfig.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicElementConfig.java
new file mode 100644
index 0000000..39f767a
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicElementConfig.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config.basics;
+
+/**
+ * Basic configuration for network elements, e.g. devices, hosts. Such elements
+ * can have a friendly name, geo-coordinates, logical rack coordinates and
+ * an owner entity.
+ */
+public abstract class BasicElementConfig<S> extends AllowedEntityConfig<S> {
+
+ public static final String NAME = "name";
+
+ public static final String LATITUDE = "latitude";
+ public static final String LONGITUDE = "longitude";
+
+ public static final String RACK_ADDRESS = "rackAddress";
+ public static final String OWNER = "owner";
+
+ /**
+ * Returns friendly label for the element.
+ *
+ * @return friendly label or element id itself if not set
+ */
+ public String name() {
+ return get(NAME, subject.toString());
+ }
+
+ /**
+ * Sets friendly label for the element.
+ *
+ * @param name new friendly label; null to clear
+ * @return self
+ */
+ public BasicElementConfig name(String name) {
+ return (BasicElementConfig) setOrClear(NAME, name);
+ }
+
+ /**
+ * Returns element latitude.
+ *
+ * @return element latitude; -1 if not set
+ */
+ public double latitude() {
+ return get(LATITUDE, -1.0);
+ }
+
+ /**
+ * Sets the element latitude.
+ *
+ * @param latitude new latitude; null to clear
+ * @return self
+ */
+ public BasicElementConfig latitude(Double latitude) {
+ return (BasicElementConfig) setOrClear(LATITUDE, latitude);
+ }
+
+ /**
+ * Returns element latitude.
+ *
+ * @return element latitude; -1 if not set
+ */
+ public double longitude() {
+ return get(LONGITUDE, -1.0);
+ }
+
+ /**
+ * Sets the element longitude.
+ *
+ * @param longitude new longitude; null to clear
+ * @return self
+ */
+ public BasicElementConfig longitude(Double longitude) {
+ return (BasicElementConfig) setOrClear(LONGITUDE, longitude);
+ }
+
+ /**
+ * Returns the element rack address.
+ *
+ * @return rack address; null if not set
+ */
+ public String rackAddress() {
+ return get(RACK_ADDRESS, null);
+ }
+
+ /**
+ * Sets element rack address.
+ *
+ * @param address new rack address; null to clear
+ * @return self
+ */
+ public BasicElementConfig rackAddress(String address) {
+ return (BasicElementConfig) setOrClear(RACK_ADDRESS, address);
+ }
+
+ /**
+ * Returns owner of the element.
+ *
+ * @return owner or null if not set
+ */
+ public String owner() {
+ return get(OWNER, null);
+ }
+
+ /**
+ * Sets the owner of the element.
+ *
+ * @param owner new owner; null to clear
+ * @return self
+ */
+ public BasicElementConfig owner(String owner) {
+ return (BasicElementConfig) setOrClear(OWNER, owner);
+ }
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicHostConfig.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicHostConfig.java
new file mode 100644
index 0000000..2f4b799
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicHostConfig.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config.basics;
+
+import org.onosproject.net.HostId;
+
+/**
+ * Basic configuration for network end-station hosts.
+ */
+public class BasicHostConfig extends BasicElementConfig<HostId> {
+
+ // TODO: determine what aspects of configuration to add for hosts
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicLinkConfig.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicLinkConfig.java
new file mode 100644
index 0000000..c881a7b
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/BasicLinkConfig.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config.basics;
+
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+
+import java.time.Duration;
+
+/**
+ * Basic configuration for network infrastructure link.
+ */
+public class BasicLinkConfig extends AllowedEntityConfig<LinkKey> {
+
+ public static final String TYPE = "type";
+ public static final String LATENCY = "latency";
+ public static final String BANDWIDTH = "bandwidth";
+
+ /**
+ * Returns the link type.
+ *
+ * @return link type override
+ */
+ public Link.Type type() {
+ return get(TYPE, Link.Type.DIRECT, Link.Type.class);
+ }
+
+ /**
+ * Sets the link type.
+ *
+ * @param type link type override
+ * @return self
+ */
+ public BasicLinkConfig type(Link.Type type) {
+ return (BasicLinkConfig) setOrClear(TYPE, type);
+ }
+
+ /**
+ * Returns link latency in terms of nanos.
+ *
+ * @return link latency; -1 if not set
+ */
+ public Duration latency() {
+ return Duration.ofNanos(get(LATENCY, -1));
+ }
+
+ /**
+ * Sets the link latency.
+ *
+ * @param latency new latency; null to clear
+ * @return self
+ */
+ public BasicElementConfig latency(Duration latency) {
+ Long nanos = latency == null ? null : latency.toNanos();
+ return (BasicElementConfig) setOrClear(LATENCY, nanos);
+ }
+
+ /**
+ * Returns link bandwidth in terms of Mbps.
+ *
+ * @return link bandwidth; -1 if not set
+ */
+ public long bandwidth() {
+ return get(BANDWIDTH, -1);
+ }
+
+ /**
+ * Sets the link bandwidth.
+ *
+ * @param bandwidth new bandwidth; null to clear
+ * @return self
+ */
+ public BasicElementConfig bandwidth(Long bandwidth) {
+ return (BasicElementConfig) setOrClear(BANDWIDTH, bandwidth);
+ }
+
+}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/SubjectFactories.java b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/SubjectFactories.java
new file mode 100644
index 0000000..257bd27
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/config/basics/SubjectFactories.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.config.basics;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.incubator.net.config.SubjectFactory;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.LinkKey;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Set of subject factories for potential configuration subjects.
+ */
+public final class SubjectFactories {
+
+ // Construction forbidden
+ private SubjectFactories() {
+ }
+
+ public static final SubjectFactory<ApplicationId> APP_SUBJECT_FACTORY =
+ new SubjectFactory<ApplicationId>(ApplicationId.class, "apps") {
+ @Override
+ public ApplicationId createSubject(String key) {
+ // FIXME: figure out how to safely create sanctioned app ids
+ return null;
+ }
+ };
+
+ public static final SubjectFactory<DeviceId> DEVICE_SUBJECT_FACTORY =
+ new SubjectFactory<DeviceId>(DeviceId.class, "devices") {
+ @Override
+ public DeviceId createSubject(String key) {
+ return DeviceId.deviceId(key);
+ }
+ };
+
+ public static final SubjectFactory<HostId> HOST_SUBJECT_FACTORY =
+ new SubjectFactory<HostId>(HostId.class, "hosts") {
+ @Override
+ public HostId createSubject(String key) {
+ return HostId.hostId(key);
+ }
+ };
+
+ public static final SubjectFactory<LinkKey> LINK_SUBJECT_FACTORY =
+ new SubjectFactory<LinkKey>(LinkKey.class, "links") {
+ @Override
+ public LinkKey createSubject(String key) {
+ String[] cps = key.split("-");
+ checkArgument(cps.length == 2, "Incorrect link key format: %s", key);
+ return LinkKey.linkKey(ConnectPoint.deviceConnectPoint(cps[0]),
+ ConnectPoint.deviceConnectPoint(cps[1]));
+ }
+ };
+
+}