ONOS-5718 Dynamic Config APIs with RPC and Notification support

Change-Id: I670890efee83c86c7a3b242783c0a62879059849
diff --git a/apps/config/BUCK b/apps/config/BUCK
new file mode 100644
index 0000000..22e1a08
--- /dev/null
+++ b/apps/config/BUCK
@@ -0,0 +1,17 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:org.apache.karaf.shell.console',
+    '//core/store/serializers:onos-core-serializers',
+    '//cli:onos-cli',
+]
+
+osgi_jar (
+    deps = COMPILE_DEPS,
+)
+
+onos_app (
+    title = 'Dynamic Config App',
+    category = 'Utility',
+    url = 'http://onosproject.org',
+    description = 'Application to support the Dynamic configuration service and store.',
+)
\ No newline at end of file
diff --git a/apps/config/pom.xml b/apps/config/pom.xml
new file mode 100755
index 0000000..de5cdc7
--- /dev/null
+++ b/apps/config/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-apps</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>onos-app-config</artifactId>
+    <packaging>bundle</packaging>
+    <description>Dynamic Config App6</description>
+    <properties>
+        <onos.app.name>org.onosproject.configapp</onos.app.name>
+        <onos.app.category>Utility</onos.app.category>
+        <onos.app.title>Dynamic Config App</onos.app.title>
+        <onos.app.url>http://onosproject.org</onos.app.url>
+        <onos.app.readme>Dynamic Config App.</onos.app.readme>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
+    </dependencies>
+
+
+
+</project>
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigEvent.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigEvent.java
new file mode 100755
index 0000000..bb29b9d
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigEvent.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-present 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.config;
+
+
+import org.onosproject.config.model.ResourceIdentifier;
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Describes a DynamicConfig change event.
+ */
+public class DynamicConfigEvent extends AbstractEvent<DynamicConfigEvent.Type, ResourceIdentifier> {
+
+    /**
+     * Type of configuration events.
+     * A configuration instance could be a leaf node or a subtree,
+     * identified by the subject, ResourceIdentifier.
+     */
+    public enum Type {
+        /**
+         * Signifies that a dynamic configuration instance was added.
+         */
+        NODE_ADDED,
+
+        /**
+         * Signifies that dynamic configuration instance was updated.
+         */
+        NODE_UPDATED,
+
+        /**
+         * Signifies that dynamic configuration instance was replaced.
+         */
+        NODE_REPLACED,
+
+        /**
+         * Signifies that dynamic configuration instance was removed.
+         */
+        NODE_DELETED
+    }
+
+    /**
+     * Creates an event of a given type, config node value and config node path.
+     *
+     * @param type  config node type
+     * @param path  config node path
+     */
+    public DynamicConfigEvent(Type type, ResourceIdentifier path) {
+        super(type, path);
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigListener.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigListener.java
new file mode 100755
index 0000000..159cead
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of receiving dynamic config change events.
+ */
+public interface DynamicConfigListener extends EventListener<DynamicConfigEvent> {
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java
new file mode 100755
index 0000000..991e806
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigService.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.config.model.ResourceIdentifier;
+import org.onosproject.config.model.DataNode;
+import org.onosproject.event.ListenerService;
+
+/**
+ * Service for storing and distributing dynamic configuration data.
+ */
+public interface DynamicConfigService
+        extends ListenerService<DynamicConfigEvent, DynamicConfigListener> {
+    /**
+     * Creates a new node in the dynamic config store.
+     * This method would throw an exception if there is a node with the same
+     * identifier, already present at the specified path or any of the parent
+     * nodes were not present in the path leading up to the requested node.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @throws FailedException if the new node could not be created
+     */
+    void createNode(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Creates a new node in the dynamic config store.
+     * Creates any missing parent nodes, leading up to the given node.
+     * This method will throw an exception if there is a node with the same
+     * identifier, already present at the specified path or any of the parent
+     * nodes were not present in the path leading up to the requested node.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @throws FailedException if the new node could not be created
+     */
+    void createNodeRecursive(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Reads the requested node form the dynamic config store.
+     * This operation would get translated to reading a leaf node or a subtree.
+     * Will return an empty DataNode if after applying the filter, the result
+     * is an empty list of nodes. This method would throw an exception if the
+     * requested node or any parent nodes in the path were not present.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @param filter filtering conditions to be applied on the result list of nodes
+     * @return a recursive data structure, holding a leaf node or a subtree
+     * @throws FailedException if the requested node could not be read
+     */
+    DataNode readNode(ResourceIdentifier path, Filter filter);
+
+    /**
+     * Returns the number of children under the node at the given path.
+     * This method would throw an exception if the requested node or any parent
+     * nodes in the path were not present.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @param filter filtering conditions to be applied on the result list of nodes
+     * @return the number of children after applying the filtering conditions if any
+     * @throws FailedException if the request failed
+     */
+    Integer getNumberOfChildren(ResourceIdentifier path, Filter filter);
+
+    /**
+     * Updates an existing node in the dynamic config store.
+     * This method would throw an exception if the requested node, any of its
+     * children or any parent nodes in the path were not present.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @throws FailedException if the update request failed
+     */
+    void updateNode(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Updates an existing node in the dynamic config store.
+     * Any missing children nodes will be created with this request.
+     * This method would throw an exception if the requested node or any of the
+     * parent nodes in the path were not present.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @throws FailedException if the update request failed for any reason
+     *
+     */
+    void updateNodeRecursive(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Replaces nodes in the dynamic config store.
+     * This will ensure that only the tree structure in the given DataNode will
+     * be in place after a replace. This method would throw an exception if
+     * the requested node or any of the parent nodes in the path were not
+     * present. Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @throws FailedException if the replace request failed
+     */
+    void replaceNode(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Removes a leaf node from the dynamic config store.
+     * This method would throw an exception if the requested node or any of the
+     * parent nodes in the path were not present or the specified node is the
+     * root node or has one or more children.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @throws FailedException if the delete request failed
+     */
+    void deleteNode(ResourceIdentifier path);
+
+    /**
+     * Removes a subtree from the dynamic config store.
+     * This method will delete all the children recursively, under the given
+     * node. It will throw an exception if the requested node or any of the
+     * parent nodes in the path were not present.
+     * Failure reason will be the error message in the exception.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @throws FailedException if the delete request failed
+     */
+    void deleteNodeRecursive(ResourceIdentifier path);
+
+    /**
+     * Adds a listener to be notified when a leaf or subtree rooted at the
+     * specified path is modified.
+     *
+     * @param path data structure with absolute path to the node being listened to
+     * @param listener listener to be notified
+     * @throws FailedException if the listener could not be added
+     */
+    void addConfigListener(ResourceIdentifier path, DynamicConfigListener listener);
+
+    /**
+     * Removes a previously added listener.
+     *
+     * @param path data structure with absolute path to the node being listened to
+     * @param listener listener to unregister
+     * @throws FailedException if the listener could not be removed
+     */
+    void removeConfigListener(ResourceIdentifier path, DynamicConfigListener listener);
+
+    /**
+     * Registers an RPC handler.
+     *
+     * @param handler RPC handler
+     * @param command RPC command
+     * @throws FailedException if the handler could not be added
+     */
+    void registerHandler(RpcHandler handler, RpcCommand command);
+
+    /**
+     * Unregisters an RPC receiver.
+     *
+     * @param handler RPC handler
+     * @param command RPC command
+     * @throws FailedException if the handler could not be removed
+     */
+    void unRegisterHandler(RpcHandler handler, RpcCommand command);
+
+    /**
+     * Invokes an RPC.
+     *
+     * @param caller of the of the RPC
+     * @param msgId RPC message id
+     * @param command RPC command
+     * @param input RPC input
+     * @throws FailedException if the RPC could not be invoked
+     */
+    void invokeRpc(RpcCaller caller, Integer msgId, RpcCommand command, RpcInput input);
+
+    /**
+     * Provides response to a a previously invoked RPC.
+     *
+     * @param msgId of a previously invoked RPC
+     * @param output data from the RPC execution
+     * @throws FailedException if the RPC response was invalid
+     * (or the msg id was not recognised by the store)
+     */
+    void rpcResponse(Integer msgId, RpcOutput output);
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java
new file mode 100644
index 0000000..c95efba
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigStore.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.config.model.DataNode;
+import org.onosproject.config.model.ResourceIdentifier;
+import org.onosproject.store.Store;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Store interface for storing and distributing dynamic configuration data.
+ */
+public interface DynamicConfigStore
+        extends Store<DynamicConfigEvent, DynamicConfigStoreDelegate> {
+    /**
+     * Adds a new node in the dynamic config store. The new node will not be
+     * added if there is a node with the same identifier, already present at
+     * the specified path or any of the parent nodes were not present in the
+     * path leading up to the requested node.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @return future that is completed with {@code true} if the new node was
+     * successfully added or completed exceptionally with
+     * {@code FailedException} if node addition failed
+     */
+    CompletableFuture<Boolean> addNode(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Adds a new node in the dynamic config store.
+     * Creates any missing parent nodes, leading up to the given node. Node
+     * will not be added if there is a node with the same identifier, already
+     * present at the specified path.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @return future that is completed with {@code true} if the node was
+     * successfully added or completed exceptionally with
+     * {@code FailedException} if the node addition failed
+     */
+    CompletableFuture<Boolean> addRecursive(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Reads the requested node from the dynamic config store.
+     * This operation would get translated to reading a leaf node or a subtree.
+     * This would fail if the requested node was not present or any parent nodes
+     * in the path were not present.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @param filter filtering conditions to be applied on the result list of nodes
+     * @return future that will be completed with a DataNode (will be an empty
+     * DataNode if after applying the filter, the result is an empty list of nodes)
+     * or completed with {@code FailedException} if the node could not be read
+     */
+    CompletableFuture<DataNode> readNode(ResourceIdentifier path, Filter filter);
+
+    /**
+     * Updates an existing node in the dynamic config store.
+     * This request would fail if the requested node, any of its children or
+     * any parent nodes in the path were not present.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @return future that is completed with {@code true} if the node was
+     * successfully updated or completed exceptionally with
+     * {@code FailedException} if the update request failed
+     */
+    CompletableFuture<Boolean> updateNode(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Updates an existing node in the dynamic config store.
+     * Any missing children will be created with this request. The update will
+     * fail if the requested node or any of the parent nodes in the path
+     * were not present.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @return future that is completed with {@code true} if the node was
+     * successfully updated or completed exceptionally with
+     * {@code FailedException} if the update request failed
+     */
+    CompletableFuture<Boolean> updateNodeRecursive(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Replaces nodes in the dynamic config store.
+     * This will ensure that only the tree structure in the given DataNode will
+     * be in place after a replace. This would fail if the requested node or
+     * any of the parent nodes in the path were not present.
+     *
+     * @param path data structure with absolute path to the parent
+     * @param node recursive data structure, holding a leaf node or a subtree
+     * @return future that is completed with {@code true} if the node was
+     * successfully replaced or completed exceptionally with
+     * {@code FailedException} if the replace request failed
+     */
+    CompletableFuture<Boolean> replaceNode(ResourceIdentifier path, DataNode node);
+
+    /**
+     * Removes  a node from the dynamic config store.
+     * This would fail if the requested node or any of the parent nodes in the
+     * path were not present or the specified node is the root node or has one
+     * or more children.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @return future that is completed with {@code true} if the node was
+     * successfully deleted or completed exceptionally with
+     * {@code FailedException} if the delete request failed
+     */
+    CompletableFuture<Boolean> deleteNode(ResourceIdentifier path);
+
+    /**
+     * Removes a subtree from the dynamic config store.
+     * This will delete all the children recursively, under the given node.
+     * Will fail if the requested node or any of the parent nodes in
+     * the path were not present.
+     *
+     * @param path data structure with absolute path to the intended node
+     * @return future that is completed with {@code true} if the delete was
+     * successful or completed exceptionally with
+     * {@code FailedException} if the delete request failed
+     */
+    CompletableFuture<Boolean> deleteNodeRecursive(ResourceIdentifier path);
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/DynamicConfigStoreDelegate.java b/apps/config/src/main/java/org/onosproject/config/DynamicConfigStoreDelegate.java
new file mode 100644
index 0000000..4cfbccc
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/DynamicConfigStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Dynamic configuration store delegate.
+ */
+public interface DynamicConfigStoreDelegate extends StoreDelegate<DynamicConfigEvent> {
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/FailedException.java b/apps/config/src/main/java/org/onosproject/config/FailedException.java
new file mode 100755
index 0000000..d74abd1
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/FailedException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present 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.config;
+
+/**
+ * Exceptions for use by the {@code DynamicConfigService}.
+ */
+public class FailedException extends RuntimeException {
+
+    /**
+     * Constructs a new runtime exception with no error message.
+     */
+    public FailedException() {
+        super();
+    }
+
+    /**
+     * Constructs a new runtime exception with the given error message.
+     *
+     * @param message error message
+     */
+    public FailedException(String message) {
+        super(message);
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/Filter.java b/apps/config/src/main/java/org/onosproject/config/Filter.java
new file mode 100755
index 0000000..377a148
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/Filter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2016-present 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.config;
+
+
+import org.onosproject.config.model.ResourceIdentifier;
+
+import java.util.Set;
+
+/**
+ * Abstraction for Filters that can be used while traversing the dynamic config store.
+ * This abstraction allows to select entries of interest based on various criteria
+ * defined by this interface.
+ * NOTE: Only criteria based on {@code ResourceIdentifier} are supported currently.
+ * This is a placeholder for a filter; Set of ResourceIdentifier becomes inefficient when
+ * using a large number of filtering criteria;
+ */
+public interface Filter {
+    enum TraversalMode {
+        /**
+         * Traversal types.
+         */
+        SUB_TREE(-1),
+        NODE_ONLY(0),
+        GIVEN_DEPTH;
+
+        /**
+         * variable indicating the depth of traversal.
+         * depth = -1 => if the node is pointing to a subtree, the entire subtree will be traversed;
+         * if the node points to a leaf, just the leaf will be retrieved.
+         * depth = 0 => tree will not be traversed; will retrieve just the specific node,
+         * irrespective of it being a subtree root or a leaf node
+         * depth = any other integer => that many levels of the subtree will be traversed;
+         * if depth > the number of levels of children, the entire subtree will
+         * be traversed and end the traversal, without throwing any errors.
+         */
+        int depth;
+
+        TraversalMode() {
+
+        }
+
+        TraversalMode(int depth) {
+            this.depth = depth;
+        }
+
+        int depth() {
+            return depth;
+        }
+    }
+
+    /**
+     * Adds the traversal depth to the Filter object.
+     * Various interpretations of depth are as mentioned.
+     * Default traversal mode is to read just the given node(NODE_ONLY).
+     *
+     * @param depth new criteria
+     */
+    void addDepth(TraversalMode depth);
+
+    /**
+     * Adds new ResourceIdentifier filtering criteria to a Filter object.
+     * If the same ResourceIdentifier is already part of the criteria
+     * for the object, it will not be added again, but will not throw any exceptions.
+     * This will not check for the validity of the ResourceIdentifier.
+     *
+     * @param add new criteria
+     */
+    void addCriteria(Set<ResourceIdentifier> add);
+
+    /**
+     * Removes the given ResourceIdentifier filtering criteria from a Filter object.
+     * If the ResourceIdentifier was NOT already part of the criteria for
+     * the object, it will not be removed, but will not throw any exceptions.
+     * This will not check for the validity of the ResourceIdentifier.
+     *
+     * @param remove criteria to be removed
+     */
+    void removeCriteria(Set<ResourceIdentifier> remove);
+
+    /**
+     * Method to list all the ResourceIdentifier criteria that are in place for a Filter.
+     *
+     * @return Set of ResourceIdentifier criteria for this entity
+     */
+    Set<ResourceIdentifier> getCriteria();
+
+    /**
+     * Method to create a filter that include all entries rejected by the criteria.
+     *
+     * @param original filter object with a criteria set
+     * @return Filter object with negated criteria set
+     * @throws InvalidFilterException if the received Filter object
+     * was null or if it had an empty criteria set
+     */
+    Filter negateFilter(Filter original);
+
+    /**
+     * Method to check if the Filter has an empty criteria set.
+     *
+     * @return {@code true} if criteria set is empty, {@code true} otherwise.
+     */
+    boolean isEmptyFilter();
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/InvalidFilterException.java b/apps/config/src/main/java/org/onosproject/config/InvalidFilterException.java
new file mode 100644
index 0000000..e583726
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/InvalidFilterException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016-present 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.config;
+
+/**
+ * Exceptions for use by the {@code ConfigFilter}.
+ */
+public class InvalidFilterException extends RuntimeException {
+
+    /**
+     * Constructs a new runtime exception with no error message.
+     */
+    public InvalidFilterException() {
+        super();
+    }
+
+    /**
+     * Constructs a new runtime exception with the given error message.
+     *
+     * @param message error message
+     */
+    public InvalidFilterException(String message) {
+        super(message);
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/RpcCaller.java b/apps/config/src/main/java/org/onosproject/config/RpcCaller.java
new file mode 100644
index 0000000..bbb9e75
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/RpcCaller.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016-present 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.config;
+
+/**
+ * Service for entities that would invoke RPCs and receive RPC responses,
+ * through the Dynamic Config brokerage.
+ */
+public interface RpcCaller {
+    /*
+     * Receives an RPC response.
+     *
+     * @param msgId of a previously invoked RPC
+     * @param output from the RPC execution
+     */
+    void receiveResponse(Integer msgId, RpcOutput output);
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/RpcCommand.java b/apps/config/src/main/java/org/onosproject/config/RpcCommand.java
new file mode 100644
index 0000000..ada6b96
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/RpcCommand.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.config.model.ResourceIdentifier;
+/**
+ * Abstract implementation of an RPC command.
+ */
+public abstract class RpcCommand {
+    /**
+     * Identifier of an RPC command.
+     */
+    ResourceIdentifier cmdId;
+
+    /**
+     * Creates an instance of RpcCommand.
+     *
+     * @param cmdId of RPC command
+     */
+    public RpcCommand(ResourceIdentifier cmdId) {
+        this.cmdId = cmdId;
+    }
+
+    /**
+     * Returns the RPC command id.
+     *
+     * @return cmdId
+     */
+    public ResourceIdentifier cmdId() {
+        return this.cmdId;
+    }
+    /**
+     * Executes the RPC command.
+     *
+     * @param input input data to the RPC command.
+     */
+    public abstract void execute(RpcInput input);
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/RpcHandler.java b/apps/config/src/main/java/org/onosproject/config/RpcHandler.java
new file mode 100644
index 0000000..c67cc6d
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/RpcHandler.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016-present 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.config;
+
+/**
+ *  Service for entities that would execute RPC methods invoked through
+ *  Dynamic Config RPC brokerage.
+ */
+public interface RpcHandler {
+    /*
+     * Executes the RPC.
+     *
+     * @param msgId of the RPC message to be executed
+     * @param cmd to be executed
+     * @param input data to the RPC command
+     */
+    void executeRpc(Integer msgId, RpcCommand cmd, RpcInput input);
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/RpcInput.java b/apps/config/src/main/java/org/onosproject/config/RpcInput.java
new file mode 100644
index 0000000..a3e9d35
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/RpcInput.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.config.model.DataNode;
+
+/**
+ * Abstraction for RPC input.
+ */
+public class RpcInput {
+    /**
+     * Input data to the RPC execution.
+     */
+    DataNode input;
+
+    /**
+     * TODO
+     * Any other meta data or contextual information
+     * to help the RPC execution can be here.
+     * Examples: List<DataNodes> to provide multiple inputs
+     * Additional info for the broker, to choose a suitable executor
+     */
+
+    /**
+     * Creates an instance of RpcInput.
+     *
+     * @param input to RPC execution
+     */
+    public RpcInput(DataNode input) {
+        this.input = input;
+    }
+
+    /**
+     * Returns RPC input.
+     *
+     * @return DataNode
+     */
+    public DataNode input() {
+        return this.input;
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/RpcOutput.java b/apps/config/src/main/java/org/onosproject/config/RpcOutput.java
new file mode 100644
index 0000000..3e7d4b3
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/RpcOutput.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016-present 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.config;
+
+import org.onosproject.config.model.DataNode;
+
+/**
+ * Abstraction for RPC output.
+ */
+public class RpcOutput {
+    public enum Status {
+        /**
+         * RPC execution was successful.
+         */
+        RPC_SUCCESS,
+        /**
+         * RPC execution failed.
+         */
+        RPC_FAILURE,
+        /**
+         * RPC execution don't have any output data.
+         */
+        RPC_NODATA,
+        /**
+         * Failed to receive a response from the receiver, within the broker specified timeout.
+         */
+        RPC_TIMEOUT,
+    }
+
+    /**
+     * Status of RPC execution.
+     */
+    Status status;
+    /**
+     * Output data from the RPC execution.
+     */
+    DataNode output;
+
+    /**
+     * Creates an instance of RpcOutput.
+     *
+     * @param status of RPC execution
+     * @param output of RPC execution
+     */
+    public RpcOutput(Status status, DataNode output) {
+        this.status = status;
+        this.output = output;
+    }
+
+    /**
+     * Returns RPC status.
+     *
+     * @return Status
+     */
+    public RpcOutput.Status status() {
+        return this.status;
+    }
+
+    /**
+     * Returns RPC output.
+     *
+     * @return DataNode
+     */
+    public DataNode output() {
+        return this.output;
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/impl/package-info.java b/apps/config/src/main/java/org/onosproject/config/impl/package-info.java
new file mode 100755
index 0000000..63a91d1
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/impl/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2016-present 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.
+ */
+
+/**
+ * Dynamic config service App and Store implementation.
+ * Work in progress; would change considerably based on
+ * the DataNode and ResourceId implementations.
+ * These are to be looked upon as placeholders
+ */
+package org.onosproject.config.impl;
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/DataNode.java b/apps/config/src/main/java/org/onosproject/config/model/DataNode.java
new file mode 100755
index 0000000..5c43304
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/DataNode.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2016-present 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.config.model;
+
+import java.util.LinkedHashMap;
+
+/**
+ * Hollow definition of DataNode for ConfigService APIs.
+ */
+public interface DataNode {
+    //will remove this when the corresponding changes in onos-yang-tools become available
+
+    /**
+     * Builder for DataNode.
+     */
+    interface Builder<V> {
+        /**
+         * clones a base Data node obj to a new one.
+         *
+         * @param base base DataNode obj to be cloned
+         * @return a DataNode builder
+         */
+        Builder addBaseObj(DataNode base);
+        /**
+         * Adds the value of the instance node.
+         *
+         * @param key of the node
+         * @return a DataNode builder
+         */
+        Builder addKey(NodeKey key);
+        /**
+         * Adds the value of the instance node.
+         *
+         * @param type of the node
+         * @return a DataNode builder
+         */
+        Builder addType(DataNode.Type type);
+        /**
+         * Adds the value of the leaf node.
+         *
+         * @param value at the node
+         * @return a DataNode builder
+         */
+        Builder addValue(String value);
+
+        /**
+         * Adds children to the children field.
+         *
+         * @param children to be added
+         * @return a DataNode builder
+         */
+        //Builder addChildren(LinkedHashMap<NodeKey, DataNode> children);
+
+        /**
+         * Builds an immutable DataNode entity.
+         *
+         * @return DataNode
+         */
+        DataNode build();
+    }
+
+    /**
+     * Returns the children if DataNode contains an inner node.
+     *
+     * @return LinkedHashMap of children for an inner node, null for a leaf node
+     */
+    LinkedHashMap<NodeKey, DataNode> children();
+
+    /**
+     * Returns the value at the leaf node as a string.
+     *
+     * @return value at the leaf node as a string, null if it is an innernode
+     */
+    String value();
+
+    /**
+     * Returns the node schema identifier.
+     *
+     * @return node schema identifier
+     */
+    SchemaIdentifier identifier();
+
+    /**
+     * Returns the type of node.
+     *
+     * @return node type
+     */
+    Type type();
+
+    /**
+     * Returns the key to identify a branching node.
+     *
+     * @return key to identify a branching node
+     */
+    NodeKey key();
+
+    /**
+     * Represents type of node in data store.
+     */
+    enum Type {
+
+        /**
+         * Single instance node.
+         */
+        SINGLE_INSTANCE_NODE,
+
+        /**
+         * Multi instance node.
+         */
+        MULTI_INSTANCE_NODE,
+
+        /**
+         * Single instance leaf node.
+         */
+        SINGLE_INSTANCE_LEAF_VALUE_NODE,
+
+        /**
+         * Multi instance leaf node.
+         */
+        MULTI_INSTANCE_LEAF_VALUE_NODE
+    }
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/DefaultDataNode.java b/apps/config/src/main/java/org/onosproject/config/model/DefaultDataNode.java
new file mode 100755
index 0000000..44b8c1e
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/DefaultDataNode.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2016-present 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.config.model;
+
+import java.util.LinkedHashMap;
+
+/**
+ * Representation of an instance node in the Dynamic config store.
+ */
+public final class DefaultDataNode implements DataNode {
+    DataNode.Type type;
+    NodeKey key;
+    //Object value;
+    String value;
+    LinkedHashMap<NodeKey, DataNode> children;
+
+    /**
+     * Creates a new DefaultDataNode.
+     *
+     * @param key node key
+     * @param type of the node
+     * @param value of leaf node
+     * @param children of the inner node
+     */
+    private DefaultDataNode(NodeKey key, DataNode.Type type,
+                            String value, LinkedHashMap<NodeKey, DataNode> children) {
+        this.type = type;
+        this.key = key;
+        this.value = value;
+        this.children = children;
+    }
+    /**
+     *
+     */
+    /**
+     * Creates a new DefaultDataNode.
+     *
+     * @param node to be cloned
+     * @param value of leaf node
+     */
+    private DefaultDataNode(DataNode node, String value) {
+        this.type = node.type();
+        this.key = node.key();
+        this.value = value;
+        this.children = null;
+    }
+    /**
+     * Creates a new DefaultDataNode.
+     *
+     * @param node to be cloned
+     * @param children to be added
+     */
+    private DefaultDataNode(DataNode node, LinkedHashMap<NodeKey, DataNode> children) {
+        this.type = node.type();
+        this.key = node.key();
+        this.value = null;
+        this.children = children;
+    }
+
+    @Override
+    public LinkedHashMap<NodeKey, DataNode> children() {
+        return this.children;
+    }
+
+    @Override
+    public  String value() {
+        return value;
+        //return value.toString();
+    }
+
+
+    /**
+     * Creates and returns a new builder instance.
+     *
+     * @return new builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final class Builder<V> implements DataNode.Builder {
+
+        private DataNode.Type type;
+        private NodeKey key;
+        //Object value;
+        private String value;
+        private LinkedHashMap<NodeKey, DataNode> children;
+
+        private Builder() {
+            this.type = null;
+            this.key = null;
+            this.value = null;
+            this.children = null;
+        }
+
+        @Override
+        public Builder addBaseObj(DataNode base) {
+            this.key = base.key();
+            this.type = base.type();
+            this.value = base.value();
+            this.children = base.children();
+            return this;
+        }
+
+        @Override
+        public Builder addKey(NodeKey key) {
+            this.key = key;
+            return this;
+        }
+
+        @Override
+        public Builder addType(DataNode.Type type) {
+            this.type = type;
+            return this;
+        }
+
+        @Override
+        public Builder addValue(String value) {
+            this.value = value;
+            return this;
+        }
+
+        //@Override
+        public Builder addChildren(LinkedHashMap<NodeKey, DataNode> children) {
+            this.children = children;
+            return this;
+        }
+
+        @Override
+        public DataNode build() {
+            return new DefaultDataNode(this.key, this.type, this.value, this.children);
+        }
+    }
+
+
+    @Override
+    public SchemaIdentifier identifier() {
+        return this.key.schemaId;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    @Override
+    public NodeKey key() {
+        return this.key;
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/DefaultResourceIdentifier.java b/apps/config/src/main/java/org/onosproject/config/model/DefaultResourceIdentifier.java
new file mode 100755
index 0000000..63aba40
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/DefaultResourceIdentifier.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016-present 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.config.model;
+
+/**
+ * Created by sdn on 12/15/16.
+ */
+public class DefaultResourceIdentifier<V> implements ResourceIdentifier     {
+    NodeKey key;
+    ResourceIdentifier next;
+
+    public DefaultResourceIdentifier(String nm, String nmspc) {
+        this.key = new NodeKey(nm, nmspc);
+        this.next = null;
+    }
+
+    public DefaultResourceIdentifier(ResourceIdentifier parent, NodeKey ckey) {
+        this.key = parent.nodeKey();
+        //new NodeKey(parent.nodeKey().schemaId.name, parent.nodeKey().schemaId.nameSpace);
+        this.next = new DefaultResourceIdentifier(ckey);
+    }
+
+    public DefaultResourceIdentifier(ResourceIdentifier parent, ResourceIdentifier child) {
+        this.key = parent.nodeKey();
+        this.next = child;
+    }
+
+    public DefaultResourceIdentifier(NodeKey nkey) {
+        this.key = nkey;
+        this.next = null;
+    }
+
+    /*public void setChild(NodeKey ckey) {
+        this.next = new DefaultResourceIdentifier(ckey);
+    }*/
+
+    @Override
+    public NodeKey nodeKey() {
+        return this.key;
+    }
+
+    @Override
+    public ResourceIdentifier descendentIdentifier() {
+        return this.next;
+    }
+
+    @Override
+    public String getBase() {
+        return this.key.schemaId.name.concat("#").concat(this.key.schemaId.nameSpace);
+    }
+
+    @Override
+    public String asString() {
+        String base = getBase();
+        ResourceIdentifier desc = next;
+        while (desc != null) {
+            base.concat(".").concat(desc.getBase());
+            desc = desc.descendentIdentifier();
+        }
+        return base;
+    }
+}
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java b/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java
new file mode 100755
index 0000000..9b462a0
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/NodeKey.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016-present 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.config.model;
+
+/**
+ * Created by sdn on 12/15/16.
+ */
+public class NodeKey {
+    SchemaIdentifier schemaId;
+
+    public NodeKey(String nm, String nmspc) {
+        this.schemaId = new SchemaIdentifier(nm, nmspc);
+    }
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/ResourceIdentifier.java b/apps/config/src/main/java/org/onosproject/config/model/ResourceIdentifier.java
new file mode 100755
index 0000000..4862fb2
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/ResourceIdentifier.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016-present 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.config.model;
+
+/**
+ * Hollow definition of ResourceIdentifier for ConfigService APIs.
+ */
+public interface ResourceIdentifier {
+    //will remove this when the corresponding changes in onos-yang-tools become available
+
+    /**
+     * Returns the node key used to uniquely identify the branch in the
+     * logical tree.
+     *
+     * @return node key uniquely identifying the branch
+     */
+    NodeKey nodeKey();
+
+    /**
+     * Returns the descendent resource identifier.
+     *
+     * @return descendent resource identifier
+     */
+    ResourceIdentifier descendentIdentifier();
+
+    String getBase();
+    String asString();
+    //DefaultResourceIdentifier asResId(NodeKey nkey);
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/SchemaIdentifier.java b/apps/config/src/main/java/org/onosproject/config/model/SchemaIdentifier.java
new file mode 100755
index 0000000..20ce4cb
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/SchemaIdentifier.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016-present 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.config.model;
+
+/**
+ * Created by sdn on 12/15/16.
+ */
+public class SchemaIdentifier {
+    String name;
+    String nameSpace;
+    SchemaIdentifier(String nm, String nmspc) {
+        this.name = nm;
+        this.nameSpace = nmspc;
+    }
+}
diff --git a/apps/config/src/main/java/org/onosproject/config/model/package-info.java b/apps/config/src/main/java/org/onosproject/config/model/package-info.java
new file mode 100755
index 0000000..c6e61b3
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/model/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2016-present 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.
+ */
+
+/**
+ * Dynamic config data model, hollow definitions for APIs.
+ * Will be REMOVED when the yang/model/* are available.
+ */
+package org.onosproject.config.model;
\ No newline at end of file
diff --git a/apps/config/src/main/java/org/onosproject/config/package-info.java b/apps/config/src/main/java/org/onosproject/config/package-info.java
new file mode 100755
index 0000000..afa5a3b
--- /dev/null
+++ b/apps/config/src/main/java/org/onosproject/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present 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.
+ */
+
+/**
+ * Dynamic config service and store APIs along with supporting classes and  interfaces.
+ */
+package org.onosproject.config;
\ No newline at end of file
diff --git a/apps/pom.xml b/apps/pom.xml
index 11e9d85..b41b3d3 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -83,6 +83,7 @@
         <module>tenbi</module>
         <module>tetunnel</module>
         <module>actn-mdsc</module>
+        <module>config</module>
         <module>restconf</module>
     </modules>