ONOS-5755: RESTCONF App: App Skeleton creation

pom file will stay the same as before, while testing, please add <module>restconf</module> at apps/pom.xml

modified by Henry's comments.

Change-Id: I55d6bd4de07f03dcad77dfa575cb54c5563c937c
diff --git a/apps/restconf/BUCK b/apps/restconf/BUCK
new file mode 100644
index 0000000..79f509b
--- /dev/null
+++ b/apps/restconf/BUCK
@@ -0,0 +1,12 @@
+BUNDLES = [
+    '//apps/restconf/api:onos-apps-restconf-api',
+    '//apps/restconf/restconfmgr:onos-apps-restconf-restconfmgr',
+]
+
+onos_app (
+  app_name = 'org.onosproject.restconf',
+  title = 'RESTCONF Application Module',
+  category = 'Utility',
+  url = 'http://onosproject.org',
+  included_bundles = BUNDLES,
+)
diff --git a/apps/restconf/api/BUCK b/apps/restconf/api/BUCK
new file mode 100644
index 0000000..97d99aa
--- /dev/null
+++ b/apps/restconf/api/BUCK
@@ -0,0 +1,10 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:jersey-client',
+    '//lib:javax.ws.rs-api',
+    '//lib:jersey-server',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/restconf/api/pom.xml b/apps/restconf/api/pom.xml
new file mode 100644
index 0000000..c9de63c
--- /dev/null
+++ b/apps/restconf/api/pom.xml
@@ -0,0 +1,53 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-app-restconf</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-restconf-api</artifactId>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-servlet</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
+
diff --git a/apps/restconf/api/src/main/java/org/onosproject/restconf/api/Patch.java b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/Patch.java
new file mode 100644
index 0000000..4af1c42
--- /dev/null
+++ b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/Patch.java
@@ -0,0 +1,32 @@
+/*
+ * 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.restconf.api;
+
+import javax.ws.rs.HttpMethod;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that the annotated method responds to HTTP PATCH requests.
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@HttpMethod("PATCH")
+public @interface Patch {
+}
\ No newline at end of file
diff --git a/apps/restconf/api/src/main/java/org/onosproject/restconf/api/RestconfException.java b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/RestconfException.java
new file mode 100644
index 0000000..523c57e
--- /dev/null
+++ b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/RestconfException.java
@@ -0,0 +1,67 @@
+/*
+ * 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.restconf.api;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import static javax.ws.rs.core.Response.Status;
+
+/**
+ * Exceptions raised during RESTCONF operations. This class extends
+ * WebApplicationException. The design intention is to create a place holder
+ * for RESTCONF specific errors and to be able to add more functions as the
+ * subsystem grows.
+ */
+public class RestconfException extends WebApplicationException {
+
+    // This is a randomly generated value. A WebApplicationException class is required to define it.
+    private static final long SERIAL_VERSION_UID = 3275970397584007046L;
+
+    /**
+     * Constructs a new RESTCONF server error exception. The caller raising this
+     * exception may pass in a HTTP error status code and an error message. The
+     * error code will be displayed to the RESTCONF client as part of the
+     * response from the RESTCONF server. The error message is a string which
+     * may be saved in a log file and may be later retrieved by the
+     * getMessage() method.
+     *
+     * @param message the detailed error message
+     * @param status  HTTP error status
+     * @throws IllegalArgumentException in case the status code is null or is not from
+     *                                  javax.ws.rs.core.Response.Status.Family
+     *                                  status code family
+     */
+    public RestconfException(String message, Status status) {
+        super(message, null, Response.status(status).build());
+    }
+
+    /**
+     * Constructs a new RESTCONF server error exception. The caller raising
+     * this exception may pass in the numerical value of a HTTP error
+     * status code, The error code will be displayed to the RESTCONF client
+     * as a response from the RESTCONF server.
+     *
+     * @param status HTTP error status
+     * @throws IllegalArgumentException in case the status code is not a valid
+     *                                  HTTP status code or if it is not from the
+     *                                  javax.ws.rs.core.Response.Status.Family
+     *                                  status code family
+     */
+    public RestconfException(int status) {
+        super((Throwable) null, Response.status(status).build());
+    }
+}
diff --git a/apps/restconf/api/src/main/java/org/onosproject/restconf/api/RestconfService.java b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/RestconfService.java
new file mode 100644
index 0000000..f44ed99
--- /dev/null
+++ b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/RestconfService.java
@@ -0,0 +1,130 @@
+/*
+ * 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.restconf.api;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.glassfish.jersey.server.ChunkedOutput;
+
+/**
+ * Abstraction of RESTCONF Server functionality according to the
+ * RESTCONF RFC (no official RFC number yet).
+ */
+public interface RestconfService {
+    /**
+     * Processes a GET request against a data resource. The
+     * target data resource is identified by its URI. If the
+     * GET operation cannot be fulfilled due to reasons such
+     * as the nonexistence of the target resource, then a
+     * RestconfException exception is raised. The proper
+     * HTTP error status code is enclosed in the exception, so
+     * that the caller may return it to the RESTCONF client to
+     * display.
+     *
+     * @param uri URI of the target data resource
+     * @return JSON representation of the data resource
+     * @throws RestconfException if the GET operation cannot be fulfilled
+     */
+    ObjectNode runGetOperationOnDataResource(String uri)
+            throws RestconfException;
+
+    /**
+     * Processes a POST request against a data resource. The location of
+     * the target resource is passed in as a URI. And the resource's
+     * content is passed in as a JSON ObjectNode. If the POST operation
+     * cannot be fulfilled due to reasons such as wrong input URIs or
+     * syntax errors in the JSON payloads, a RestconfException exception
+     * is raised. The proper HTTP error status code is enclosed in the
+     * exception.
+     *
+     * @param uri      URI of the data resource to be created
+     * @param rootNode JSON representation of the data resource
+     * @throws RestconfException if the POST operation cannot be fulfilled
+     */
+    void runPostOperationOnDataResource(String uri, ObjectNode rootNode)
+            throws RestconfException;
+
+    /**
+     * Processes a PUT request against a data resource. The location of
+     * the target resource is passed in as a URI. And the resource's
+     * content is passed in as a JSON ObjectNode. If the PUT operation
+     * cannot be fulfilled due to reasons such as wrong input URIs or
+     * syntax errors in the JSON payloads, a RestconfException exception
+     * is raised. The proper HTTP error status code is enclosed in the
+     * exception.
+     *
+     * @param uri      URI of the data resource to be created or updated
+     * @param rootNode JSON representation of the data resource
+     * @throws RestconfException if the PUT operation cannot be fulfilled
+     */
+    void runPutOperationOnDataResource(String uri, ObjectNode rootNode)
+            throws RestconfException;
+
+    /**
+     * Processes the DELETE operation against a data resource. The target
+     * data resource is identified by its URI. If the DELETE operation
+     * cannot be fulfilled due reasons such as the nonexistence of the
+     * target resource, a RestconfException exception is raised. The
+     * proper HTTP error status code is enclosed in the exception.
+     *
+     * @param uri URI of the data resource to be deleted
+     * @throws RestconfException if the DELETE operation cannot be fulfilled
+     */
+    void runDeleteOperationOnDataResource(String uri) throws RestconfException;
+
+    /**
+     * Processes a PATCH operation on a data resource. The target data
+     * resource is identified by its URI passed in by the caller.
+     * And the content of the data resource is passed in as a JSON ObjectNode.
+     * If the PATCH operation cannot be fulfilled due reasons such as
+     * the nonexistence of the target resource, a RestconfException
+     * exception is raised. The proper HTTP error status code is
+     * enclosed in the exception.
+     *
+     * @param uri      URI of the data resource to be patched
+     * @param rootNode JSON representation of the data resource
+     * @throws RestconfException if the PATCH operation cannot be fulfilled
+     */
+    void runPatchOperationOnDataResource(String uri, ObjectNode rootNode)
+            throws RestconfException;
+
+    /**
+     * Retrieves the RESTCONF Root directory.
+     *
+     * @return the RESTCONF Root directory
+     */
+    String getRestconfRootPath();
+
+    /**
+     * Handles an Event Stream subscription request. This function creates
+     * a worker thread to listen to events and writes to a ChunkedOutput,
+     * which is passed in from the caller. (The worker thread blocks if
+     * no events arrive.) The ChuckedOutput is a pipe to which this
+     * function acts as the writer and the caller the reader.
+     * <p>
+     * If the Event Stream cannot be subscribed due to reasons such as
+     * the nonexistence of the target stream or failure to allocate
+     * worker thread to handle the request, a RestconfException exception
+     * is raised. The proper HTTP error status code is enclosed in the
+     * exception, so that the caller may return it to the RESTCONF client
+     * to display.
+     *
+     * @param streamId ID of the RESTCONF stream to subscribe
+     * @param output   A string data stream
+     * @throws RestconfException if the Event Stream cannot be subscribed
+     */
+    void subscribeEventStream(String streamId, ChunkedOutput<String> output)
+            throws RestconfException;
+}
diff --git a/apps/restconf/api/src/main/java/org/onosproject/restconf/api/package-info.java b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/package-info.java
new file mode 100644
index 0000000..273e398
--- /dev/null
+++ b/apps/restconf/api/src/main/java/org/onosproject/restconf/api/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.
+ */
+
+/**
+ * RESTCONF Server Public Interface. All public interfaces/APIs that might be used by
+ * external applications should be packaged here.
+ */
+package org.onosproject.restconf.api;
diff --git a/apps/restconf/app/app.xml b/apps/restconf/app/app.xml
new file mode 100644
index 0000000..d5f0ecd
--- /dev/null
+++ b/apps/restconf/app/app.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+<app name="org.onosproject.restconf" origin="ON.Lab" version="${project.version}"
+     category="Utility" url="http://onosproject.org" title="RESTCONF Service Module App"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}" >
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/onos-restconf-api/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-restconf-restconfmanager/${project.version}</artifact>
+</app>
diff --git a/apps/restconf/app/features.xml b/apps/restconf/app/features.xml
new file mode 100644
index 0000000..1cbad5a
--- /dev/null
+++ b/apps/restconf/app/features.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/onos-restconf-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-restconf-restconfmanager/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/apps/restconf/app/pom.xml b/apps/restconf/app/pom.xml
new file mode 100644
index 0000000..29dc0c2
--- /dev/null
+++ b/apps/restconf/app/pom.xml
@@ -0,0 +1,50 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-app-restconf</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-restconf-app</artifactId>
+    <packaging>pom</packaging>
+
+    <properties>
+        <onos.app.readme>RESTCONF Application Module main Application.</onos.app.readme>
+    </properties>
+
+    <description>RESTCONF Service Module main Application</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-restconf-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-restconf-restconfmanager</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/apps/restconf/pom.xml b/apps/restconf/pom.xml
new file mode 100644
index 0000000..ec32ba3
--- /dev/null
+++ b/apps/restconf/pom.xml
@@ -0,0 +1,38 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>onos-app-restconf</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>api</module>
+        <module>restconfmgr</module>
+        <module>app</module>
+    </modules>
+
+    <description>RESTCONF Application Module</description>
+</project>
diff --git a/apps/restconf/restconfmgr/BUCK b/apps/restconf/restconfmgr/BUCK
new file mode 100644
index 0000000..d661d74
--- /dev/null
+++ b/apps/restconf/restconfmgr/BUCK
@@ -0,0 +1,13 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:jersey-client',
+    '//lib:jersey-server',
+    '//lib:javax.ws.rs-api',
+    '//utils/rest:onlab-rest',
+    '//core/store/serializers:onos-core-serializers',
+    '//apps/restconf/api:onos-apps-restconf-api',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/restconf/restconfmgr/pom.xml b/apps/restconf/restconfmgr/pom.xml
new file mode 100644
index 0000000..2ddbe23
--- /dev/null
+++ b/apps/restconf/restconfmgr/pom.xml
@@ -0,0 +1,75 @@
+<?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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-app-restconf</artifactId>
+        <version>1.9.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-restconf-restconfmanager</artifactId>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-restconf-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>org.onosproject</groupId>
+          <artifactId>onlab-junit</artifactId>
+          <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java b/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java
new file mode 100644
index 0000000..45c1a4c
--- /dev/null
+++ b/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/RestconfManager.java
@@ -0,0 +1,242 @@
+/*
+ * 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.restconf.restconfmanager;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.glassfish.jersey.server.ChunkedOutput;
+import org.onosproject.event.ListenerTracker;
+import org.onosproject.restconf.api.RestconfException;
+import org.onosproject.restconf.api.RestconfService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+
+/*
+ * Skeletal ONOS RESTCONF Server application. The RESTCONF Manager
+ * implements the main logic of the RESTCONF Server.
+ *
+ * The design of the RESTCONF subsystem contains 2 major bundles:
+ *
+ * 1. RESTCONF Protocol Proxy (RPP). This bundle is implemented as a
+ *    JAX-RS application. It acts as the frond-end of the RESTCONF server.
+ *    It intercepts/handles HTTP requests that are sent to the RESTCONF
+ *    Root Path. It then calls the RESTCONF Manager to process the requests.
+ *
+ * 2. RESTCONF Manager. This bundle module is the back-end of the server.
+ *    It provides the main logic of the RESTCONF server. It interacts with
+ *    the YMS (YANG Management System) to run operations on the YANG data
+ *    objects (i.e., data resources).
+ */
+
+/**
+ * Implementation of the RestconfService interface. The class is designed
+ * as a Apache Flex component. Note that to avoid unnecessary
+ * activation, the @Component annotation's immediate parameter is set to false.
+ * So the component is not activated until a RESTCONF request is received by
+ * the RESTCONF Protocol Proxy (RPP) module, which consumes the service.
+ */
+@Component(immediate = false)
+@Service
+public class RestconfManager implements RestconfService {
+
+    private static final String RESTCONF_ROOT = "/onos/restconf";
+    private static final int THREAD_TERMINATION_TIMEOUT = 10;
+
+    // Jersey's default chunk parser uses "\r\n" as the chunk separator.
+    private static final String EOL = "\r\n";
+
+    private final int maxNumOfWorkerThreads = 5;
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private ListenerTracker listeners;
+
+    private ConcurrentMap<String, BlockingQueue<ObjectNode>> eventQueueList =
+            new ConcurrentHashMap<>();
+
+    private ExecutorService workerThreadPool;
+
+    @Activate
+    protected void activate() {
+        workerThreadPool = Executors
+                .newFixedThreadPool(maxNumOfWorkerThreads,
+                                    new ThreadFactoryBuilder()
+                                            .setNameFormat("restconf-worker")
+                                            .build());
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        shutdownAndAwaitTermination(workerThreadPool);
+        log.info("Stopped");
+    }
+
+    @Override
+    public ObjectNode runGetOperationOnDataResource(String uri)
+            throws RestconfException {
+
+        return null;
+    }
+
+    @Override
+    public void runPostOperationOnDataResource(String uri, ObjectNode rootNode)
+            throws RestconfException {
+    }
+
+    @Override
+    public void runPutOperationOnDataResource(String uri, ObjectNode rootNode)
+            throws RestconfException {
+    }
+
+    @Override
+    public void runDeleteOperationOnDataResource(String uri)
+            throws RestconfException {
+    }
+
+    @Override
+    public void runPatchOperationOnDataResource(String uri, ObjectNode rootNode)
+            throws RestconfException {
+    }
+
+    @Override
+    public String getRestconfRootPath() {
+        return RESTCONF_ROOT;
+    }
+
+    /**
+     * Creates a worker thread to listen to events and write to chunkedOutput.
+     * The worker thread blocks if no events arrive.
+     *
+     * @param streamId the RESTCONF stream id to which the client subscribes
+     * @param output   the string data stream
+     * @throws RestconfException if the worker thread fails to create
+     */
+    @Override
+    public void subscribeEventStream(String streamId,
+                                     ChunkedOutput<String> output)
+            throws RestconfException {
+        if (workerThreadPool instanceof ThreadPoolExecutor) {
+            if (((ThreadPoolExecutor) workerThreadPool).getActiveCount() >=
+                    maxNumOfWorkerThreads) {
+                throw new RestconfException("no more work threads left to " +
+                                                    "handle event subscription",
+                                            INTERNAL_SERVER_ERROR);
+            }
+        } else {
+            throw new RestconfException("Server ERROR: workerThreadPool NOT " +
+                                                "instanceof ThreadPoolExecutor",
+                                        INTERNAL_SERVER_ERROR);
+
+        }
+
+        BlockingQueue<ObjectNode> eventQueue = new LinkedBlockingQueue<>();
+        workerThreadPool.submit(new EventConsumer(output, eventQueue));
+    }
+
+    /**
+     * Shutdown a pool cleanly if possible.
+     *
+     * @param pool an executorService
+     */
+    private void shutdownAndAwaitTermination(ExecutorService pool) {
+        pool.shutdown(); // Disable new tasks from being submitted
+        try {
+            // Wait a while for existing tasks to terminate
+            if (!pool.awaitTermination(THREAD_TERMINATION_TIMEOUT, SECONDS)) {
+                pool.shutdownNow(); // Cancel currently executing tasks
+                // Wait a while for tasks to respond to being cancelled
+                if (!pool.awaitTermination(THREAD_TERMINATION_TIMEOUT,
+                                           SECONDS)) {
+                    log.error("Pool did not terminate");
+                }
+            }
+        } catch (Exception ie) {
+            // (Re-)Cancel if current thread also interrupted
+            pool.shutdownNow();
+            // Preserve interrupt status
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    /**
+     * Implementation of a worker thread which reads data from a
+     * blocking queue and writes the data to a given chunk output stream.
+     * The thread is blocked when no data arrive to the queue and is
+     * terminated when the chunk output stream is closed (i.e., the
+     * HTTP-keep-alive session is closed).
+     */
+    private class EventConsumer implements Runnable {
+
+        private String queueId;
+        private final ChunkedOutput<String> output;
+        private final BlockingQueue<ObjectNode> bqueue;
+
+        public EventConsumer(ChunkedOutput<String> output,
+                             BlockingQueue<ObjectNode> q) {
+            this.output = output;
+            this.bqueue = q;
+        }
+
+        @Override
+        public void run() {
+            try {
+                queueId = String.valueOf(Thread.currentThread().getId());
+                eventQueueList.put(queueId, bqueue);
+                log.debug("EventConsumer thread created: {}", queueId);
+
+                ObjectNode chunk;
+                while ((chunk = bqueue.take()) != null) {
+                    output.write(chunk.toString().concat(EOL));
+                }
+            } catch (IOException e) {
+                log.debug("chunkedOuput is closed: {}", this.bqueue.toString());
+                /*
+                 * Remove queue from the queue list, so that the event producer
+                 * (i.e., listener) would stop working.
+                 */
+                eventQueueList.remove(this.queueId);
+            } catch (InterruptedException e) {
+                log.error("ERROR: EventConsumer: bqueue.take() " +
+                                  "has been interrupted.");
+                log.debug("EventConsumer Exception:", e);
+            } finally {
+                try {
+                    output.close();
+                    log.debug("EventConsumer thread terminated: {}", queueId);
+                } catch (IOException e) {
+                    log.error("ERROR: EventConsumer: ", e);
+                }
+            }
+        }
+    }
+}
diff --git a/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/package-info.java b/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/package-info.java
new file mode 100644
index 0000000..b767e4a
--- /dev/null
+++ b/apps/restconf/restconfmgr/src/main/java/org/onosproject/restconf/restconfmanager/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.
+ */
+
+/**
+ * RESTCONF Service Manager implementation.
+ */
+package org.onosproject.restconf.restconfmanager;