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