[Falcon] CORD-368 Skeleton of service dependency APIs

- Changed service ID from VNI to network ID
- Added REST APIs(POST/DELETE/PUT)
- Added interfaces to CordVtnService(create/remove)
- Renamed Service/ServiceId to more specific

Change-Id: I80322fea28a7740a2cc7723b576e7bb9ff08389e
diff --git a/apps/cordvtn/pom.xml b/apps/cordvtn/pom.xml
index db8174d..085ca47 100644
--- a/apps/cordvtn/pom.xml
+++ b/apps/cordvtn/pom.xml
@@ -33,6 +33,13 @@
 
     <properties>
         <onos.app.name>org.onosproject.cordvtn</onos.app.name>
+        <web.context>/onos/cordvtn</web.context>
+        <api.version>1.0.0</api.version>
+        <api.title>CORD VTN REST API</api.title>
+        <api.description>
+            APIs for interacting with the CORD VTN application.
+        </api.description>
+        <api.package>org.onosproject.cordvtn.rest</api.package>
         <onos.app.requires>
             org.onosproject.ovsdb,
             org.onosproject.openstackswitching
@@ -102,4 +109,47 @@
         </dependency>
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Include-Resource>
+                            WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
+                            {maven-resources}
+                        </Include-Resource>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            org.slf4j,
+                            org.osgi.framework,
+                            javax.ws.rs,
+                            javax.ws.rs.core,
+                            com.sun.jersey.api.core,
+                            com.sun.jersey.spi.container.servlet,
+                            com.sun.jersey.server.impl.container.servlet,
+                            com.fasterxml.jackson.databind,
+                            com.fasterxml.jackson.databind.node,
+                            com.fasterxml.jackson.core,
+                            org.apache.karaf.shell.commands,
+                            org.apache.karaf.shell.console,
+                            com.google.common.*,
+                            org.onlab.packet.*,
+                            org.onlab.rest.*,
+                            org.onosproject.*,
+                            org.onlab.util.*,
+                            org.jboss.netty.util.*
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
 </project>
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/Service.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java
similarity index 74%
rename from apps/cordvtn/src/main/java/org/onosproject/cordvtn/Service.java
rename to apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java
index 2c31ccc..2e4a59e 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/Service.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java
@@ -21,7 +21,7 @@
 
 import java.util.Objects;
 
-public final class Service {
+public final class CordService {
 
     enum ServiceType {
         PRIVATE,
@@ -31,8 +31,8 @@
         PUBLIC_INDIRECT
     }
 
-    private final ServiceId serviceId;
-    private final String networkId;
+    private final CordServiceId id;
+    private final long segmentationId;
     private final ServiceType serviceType;
     private final IpPrefix serviceIpRange;
     private final IpAddress serviceIp;
@@ -40,16 +40,16 @@
     /**
      * Default constructor.
      *
-     * @param serviceId service id
-     * @param networkId OpenStack Neutron network id
+     * @param id service id, which is identical to OpenStack network id
+     * @param segmentationId segmentation id, which is identical to VNI
      * @param serviceType service type
      * @param serviceIpRange service ip range
      * @param serviceIp service ip
      */
-    public Service(ServiceId serviceId, String networkId, ServiceType serviceType,
+    public CordService(CordServiceId id, long segmentationId, ServiceType serviceType,
                    IpPrefix serviceIpRange, IpAddress serviceIp) {
-        this.serviceId = serviceId;
-        this.networkId = networkId;
+        this.id = id;
+        this.segmentationId = segmentationId;
         this.serviceType = serviceType;
         this.serviceIpRange = serviceIpRange;
         this.serviceIp = serviceIp;
@@ -60,17 +60,17 @@
      *
      * @return service id
      */
-    public ServiceId serviceId() {
-        return serviceId;
+    public CordServiceId id() {
+        return id;
     }
 
     /**
-     * Returns OpenStack Neutron network ID of this service.
+     * Returns segmentation ID of this service.
      *
-     * @return network id
+     * @return segmentation id
      */
-    public String networkId() {
-        return networkId;
+    public long segmentationId() {
+        return segmentationId;
     }
 
     /**
@@ -102,7 +102,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(serviceId);
+        return Objects.hash(id);
     }
 
     @Override
@@ -110,18 +110,18 @@
         if (this == obj) {
             return true;
         }
-        if (!(obj instanceof Service)) {
+        if (!(obj instanceof CordService)) {
             return false;
         }
-        final Service other = (Service) obj;
-        return Objects.equals(this.serviceId, other.serviceId);
+        final CordService other = (CordService) obj;
+        return Objects.equals(this.id, other.id);
     }
 
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
-                .add("serviceId", serviceId)
-                .add("networkId", networkId)
+                .add("id", id)
+                .add("segmentationId", segmentationId)
                 .add("serviceType", serviceType)
                 .add("serviceIpRange", serviceIpRange)
                 .add("serviceIp", serviceIp)
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/ServiceId.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordServiceId.java
similarity index 64%
rename from apps/cordvtn/src/main/java/org/onosproject/cordvtn/ServiceId.java
rename to apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordServiceId.java
index 0971692..c8f1176 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/ServiceId.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordServiceId.java
@@ -19,30 +19,33 @@
 
 import java.util.Objects;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * Representation of service identifier.
  */
-public final class ServiceId {
+public final class CordServiceId {
 
-    private final long serviceId;
+    private final String id;
 
     /**
      * Default constructor.
      *
-     * @param serviceId service identifier
+     * @param id service identifier
      */
-    private ServiceId(long serviceId) {
-        this.serviceId = serviceId;
+    private CordServiceId(String id) {
+        this.id = id;
     }
 
     /**
-     * Returns the ServiceId with value.
+     * Returns the CordServiceId with value.
      *
-     * @param serviceId service id
-     * @return ServiceId
+     * @param id service id
+     * @return CordServiceId
      */
-    public static ServiceId of(long serviceId) {
-        return new ServiceId(serviceId);
+    public static CordServiceId of(String id) {
+        checkNotNull(id);
+        return new CordServiceId(id);
     }
 
     /**
@@ -50,13 +53,13 @@
      *
      * @return service id
      */
-    public long serviceId() {
-        return serviceId;
+    public String id() {
+        return id;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(serviceId);
+        return Objects.hash(id);
     }
 
     @Override
@@ -64,17 +67,17 @@
         if (this == obj) {
             return true;
         }
-        if (!(obj instanceof ServiceId)) {
+        if (!(obj instanceof CordServiceId)) {
             return false;
         }
-        final ServiceId other = (ServiceId) obj;
-        return Objects.equals(this.serviceId, other.serviceId);
+        final CordServiceId other = (CordServiceId) obj;
+        return Objects.equals(this.id, other.id);
     }
 
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
-                .add("serviceId", serviceId)
+                .add("id", id)
                 .toString();
     }
 }
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
index fe196e1..d1ff7f0 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
@@ -277,11 +277,19 @@
     }
 
     @Override
-    public void createServiceDependency(ServiceId tenantServiceId, ServiceId providerServiceId) {
+    public void createServiceDependency(CordServiceId tenantCordServiceId,
+                                        CordServiceId providerCordServiceId) {
+        CordService tenantService = getCordService(tenantCordServiceId);
+        CordService providerService = getCordService(providerCordServiceId);
+
+        // TODO populate flow rules to create service dependency
     }
 
     @Override
-    public void removeServiceDependency(ServiceId tenantServiceId, ServiceId providerServiceId) {
+    public void removeServiceDependency(CordServiceId tenantCordServiceId) {
+        CordService tenantService = getCordService(tenantCordServiceId);
+
+        //TODO uninstall flow rules to remove service dependency
     }
 
     /**
@@ -688,6 +696,23 @@
     }
 
     /**
+     * Returns OpenStack network associated with a given CORD service.
+     *
+     * @param serviceId service id
+     * @return cord service, or null if it fails to get network from OpenStack
+     */
+    private CordService getCordService(CordServiceId serviceId) {
+        OpenstackNetwork vNet = openstackService.network(serviceId.id());
+        if (vNet == null) {
+            log.warn("Couldn't find OpenStack network for service {}", serviceId.id());
+            return null;
+        }
+
+        // TODO create CordService with network/subnet information from Neutron
+        return null;
+    }
+
+    /**
      * Installs flow rules for a given OpenStack network.
      *
      * @param vNet OpenStack network
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java
index 7bbc1e3..29b4525 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java
@@ -67,18 +67,17 @@
     List<CordVtnNode> getNodes();
 
     /**
-     * Creates a dependency between two services.
+     * Creates dependencies for a given tenant service.
      *
-     * @param tenantServiceId id of the service which has a dependency
-     * @param providerServiceId id of the service which provides dependency
+     * @param tenantCordServiceId id of the service which has a dependency
+     * @param providerCordServiceId id of the service which provide dependency
      */
-    void createServiceDependency(ServiceId tenantServiceId, ServiceId providerServiceId);
+    void createServiceDependency(CordServiceId tenantCordServiceId, CordServiceId providerCordServiceId);
 
     /**
-     * Removes a dependency between two services.
+     * Removes all dependencies from a given tenant service.
      *
-     * @param tenantServiceId id of the service which has a dependency
-     * @param providerServiceId id of the service which provides dependency
+     * @param tenantCordServiceId id of the service which has a dependency
      */
-    void removeServiceDependency(ServiceId tenantServiceId, ServiceId providerServiceId);
+    void removeServiceDependency(CordServiceId tenantCordServiceId);
 }
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ApiDocRegistrator.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ApiDocRegistrator.java
deleted file mode 100644
index b6e876f..0000000
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ApiDocRegistrator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.cordvtn.rest;
-
-import org.apache.felix.scr.annotations.Component;
-import org.onosproject.rest.AbstractApiDocRegistrator;
-import org.onosproject.rest.ApiDocProvider;
-
-@Component(immediate = true)
-public class ApiDocRegistrator extends AbstractApiDocRegistrator {
-    public ApiDocRegistrator() {
-        super(new ApiDocProvider("/onos/cordvtn",
-                                 "CORD VTN Service REST API",
-                                 ApiDocRegistrator.class.getClassLoader()));
-    }
-}
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java
new file mode 100644
index 0000000..51dd3c6
--- /dev/null
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.cordvtn.rest;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * CORD VTN Web application.
+ */
+public class CordVtnWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(ServiceDependencyWebResource.class);
+    }
+}
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
index 77822f2..d2c5567 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
@@ -15,13 +15,74 @@
  */
 package org.onosproject.cordvtn.rest;
 
+import org.onosproject.cordvtn.CordVtnService;
+import org.onosproject.cordvtn.CordServiceId;
 import org.onosproject.rest.AbstractWebResource;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 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 java.io.InputStream;
 
 /**
  * Manages service dependency.
  */
 @Path("service-dependency")
 public class ServiceDependencyWebResource extends AbstractWebResource {
+
+    private final CordVtnService service = get(CordVtnService.class);
+
+    /**
+     * Creates service dependencies.
+     *
+     * @param tServiceId tenant service id
+     * @param pServiceId provider service id
+     * @return 200 OK
+     */
+    @POST
+    @Path("{tenantServiceId}/{providerServiceId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
+                                            @PathParam("providerServiceId") String pServiceId) {
+        service.createServiceDependency(CordServiceId.of(tServiceId), CordServiceId.of(pServiceId));
+        return Response.status(Response.Status.OK).build();
+    }
+
+    /**
+     * Removes service dependencies.
+     *
+     * @param serviceId service id
+     * @return 200 OK, or 400 Bad Request
+     */
+    @DELETE
+    @Path("{serviceId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response removeServiceDependency(@PathParam("serviceId") String serviceId) {
+        service.removeServiceDependency(CordServiceId.of(serviceId));
+        return Response.status(Response.Status.OK).build();
+    }
+
+    /**
+     * Updates service dependencies.
+     *
+     * @param serviceId service id
+     * @param stream input JSON
+     * @return 200 OK, or 400 Bad Request
+     */
+    @PUT
+    @Path("{serviceId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateServiceDependency(@PathParam("serviceId") String serviceId,
+                                            InputStream stream) {
+        // TODO define input stream
+        return Response.status(Response.Status.OK).build();
+    }
 }
diff --git a/apps/cordvtn/src/main/webapp/WEB-INF/web.xml b/apps/cordvtn/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..b482a22
--- /dev/null
+++ b/apps/cordvtn/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<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>CORD VTN REST API v1.0</display-name>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Secured</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>admin</role-name>
+        </auth-constraint>
+    </security-constraint>
+
+    <security-role>
+        <role-name>admin</role-name>
+    </security-role>
+
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>karaf</realm-name>
+    </login-config>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.onosproject.cordvtn.rest.CordVtnWebApplication</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>