[VOL-3836] Extract the OLT pipeliners from ONOS

Change-Id: I0dc99aabcb17b46fc5dc8bbe8e3bbd5ece52058a
diff --git a/web/pom.xml b/web/pom.xml
new file mode 100644
index 0000000..fdbb820
--- /dev/null
+++ b/web/pom.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Foundation
+  ~
+  ~ 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>
+        <groupId>org.opencord</groupId>
+        <artifactId>olt</artifactId>
+        <version>4.4.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>olt-web</artifactId>
+    <packaging>bundle</packaging>
+    <description>REST API for OLT application for CORD</description>
+
+    <properties>
+        <web.context>/onos/olt</web.context>
+        <api.version>1.0.0</api.version>
+        <api.title>ONOS OLT REST API</api.title>
+        <api.description>
+            APIs for interacting with the CORD OLT application.
+        </api.description>
+        <api.package>org.opencord.olt.rest</api.package>
+        <olt.api.version>${project.version}</olt.api.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>olt-api</artifactId>
+            <version>${olt.api.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>olt-impl</artifactId>
+            <version>${olt.api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>sadis-api</artifactId>
+            <version>${sadis.api.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${onos.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${onos.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Include-Resource>
+                            WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
+                            {maven-resources}
+                        </Include-Resource>
+                        <Import-Package>
+                            *,org.glassfish.jersey.servlet
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                        <Karaf-Commands>org.opencord.olt.cli</Karaf-Commands>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/web/src/main/java/org/opencord/olt/rest/OltWebResource.java b/web/src/main/java/org/opencord/olt/rest/OltWebResource.java
new file mode 100644
index 0000000..54af4ac
--- /dev/null
+++ b/web/src/main/java/org/opencord/olt/rest/OltWebResource.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.opencord.olt.rest;
+
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.rest.AbstractWebResource;
+import org.opencord.olt.AccessDeviceService;
+import org.opencord.olt.AccessSubscriberId;
+
+import java.util.Optional;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+
+/**
+ * OLT REST APIs.
+ */
+
+@Path("oltapp")
+public class OltWebResource extends AbstractWebResource {
+
+    /**
+     * Provision a subscriber.
+     *
+     * @param device device id
+     * @param port port number
+     * @return 200 OK or 500 Internal Server Error
+     */
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{device}/{port}")
+    public Response provisionSubscriber(
+            @PathParam("device") String device,
+            @PathParam("port") long port) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+        DeviceId deviceId = DeviceId.deviceId(device);
+        PortNumber portNumber = PortNumber.portNumber(port);
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, portNumber);
+        try {
+            service.provisionSubscriber(connectPoint);
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).build();
+        }
+        return ok("").build();
+    }
+
+    /**
+     * Remove the provisioning for a subscriber.
+     *
+     * @param device device id
+     * @param port port number
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Path("{device}/{port}")
+    public Response removeSubscriber(
+            @PathParam("device")String device,
+            @PathParam("port")long port) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+        DeviceId deviceId = DeviceId.deviceId(device);
+        PortNumber portNumber = PortNumber.portNumber(port);
+        ConnectPoint connectPoint = new ConnectPoint(deviceId, portNumber);
+        service.removeSubscriber(connectPoint);
+        return Response.noContent().build();
+    }
+
+    /**
+     * Provision service for a subscriber.
+     *
+     * @param portName Name of the port on which the subscriber is connected
+     * @return 200 OK or 204 NO CONTENT
+     */
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("services/{portName}")
+    public Response provisionServices(
+            @PathParam("portName") String portName) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+
+        Optional<VlanId> emptyVlan = Optional.empty();
+        Optional<Integer> emptyTpId = Optional.empty();
+        if (service.provisionSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan, emptyTpId)) {
+            return ok("").build();
+        }
+        return Response.noContent().build();
+    }
+
+    /**
+     * Provision service with particular tags for a subscriber.
+     *
+     * @param portName Name of the port on which the subscriber is connected
+     * @param sTagVal  additional outer tag on this port
+     * @param cTagVal  additional innter tag on this port
+     * @param tpIdVal  technology profile id
+     * @return 200 OK or 204 NO CONTENT
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("services/{portName}/{sTag}/{cTag}/{tpId}")
+    public Response provisionAdditionalVlans(
+            @PathParam("portName") String portName,
+            @PathParam("sTag") String sTagVal,
+            @PathParam("cTag") String cTagVal,
+            @PathParam("tpId") String tpIdVal) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+        VlanId cTag = VlanId.vlanId(cTagVal);
+        VlanId sTag = VlanId.vlanId(sTagVal);
+        Integer tpId = Integer.valueOf(tpIdVal);
+
+        if (service.provisionSubscriber(new AccessSubscriberId(portName), Optional.of(sTag),
+                Optional.of(cTag), Optional.of(tpId))) {
+            return ok("").build();
+        }
+        return Response.noContent().build();
+    }
+
+    /**
+     * Removes services for a subscriber.
+     *
+     * @param portName Name of the port on which the subscriber is connected
+     * @return 200 OK or 204 NO CONTENT
+     */
+    @DELETE
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("services/{portName}")
+    public Response deleteServices(
+            @PathParam("portName") String portName) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+
+        Optional<VlanId> emptyVlan = Optional.empty();
+        Optional<Integer> emptyTpId = Optional.empty();
+        if (service.removeSubscriber(new AccessSubscriberId(portName), emptyVlan, emptyVlan, emptyTpId)) {
+            return ok("").build();
+        }
+        return Response.noContent().build();
+    }
+
+    /**
+     * Removes additional vlans of a particular subscriber.
+     *
+     * @param portName Name of the port on which the subscriber is connected
+     * @param sTagVal  additional outer tag on this port which needs to be removed
+     * @param cTagVal  additional inner tag on this port which needs to be removed
+     * @param tpIdVal  additional technology profile id
+     * @return 200 OK or 204 NO CONTENT
+     */
+    @DELETE
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("services/{portName}/{sTag}/{cTag}/{tpId}")
+    public Response removeAdditionalVlans(
+            @PathParam("portName") String portName,
+            @PathParam("sTag") String sTagVal,
+            @PathParam("cTag") String cTagVal,
+            @PathParam("tpId") String tpIdVal) {
+        AccessDeviceService service = get(AccessDeviceService.class);
+        VlanId cTag = VlanId.vlanId(cTagVal);
+        VlanId sTag = VlanId.vlanId(sTagVal);
+        Integer tpId = Integer.valueOf(tpIdVal);
+
+        if (service.removeSubscriber(new AccessSubscriberId(portName), Optional.of(sTag),
+                Optional.of(cTag), Optional.of(tpId))) {
+            return ok("").build();
+        }
+        return Response.noContent().build();
+    }
+
+}
diff --git a/web/src/main/java/org/opencord/olt/rest/package-info.java b/web/src/main/java/org/opencord/olt/rest/package-info.java
new file mode 100644
index 0000000..20cee79
--- /dev/null
+++ b/web/src/main/java/org/opencord/olt/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+/**
+ * REST APIs for the OLT application.
+ */
+package org.opencord.olt.rest;
diff --git a/web/src/main/webapp/WEB-INF/web.xml b/web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..5e33abe
--- /dev/null
+++ b/web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016-present Open Networking Foundation
+  ~
+  ~ 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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>OLT REST API v1.0</display-name>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>jersey.config.server.provider.classnames</param-name>
+            <param-value>
+                org.opencord.olt.rest.OltWebResource
+            </param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>