Hyunsun Moon
Committed by Gerrit Code Review

[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
......@@ -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>
......
......@@ -21,7 +21,7 @@ import org.onlab.packet.IpPrefix;
import java.util.Objects;
public final class Service {
public final class CordService {
enum ServiceType {
PRIVATE,
......@@ -31,8 +31,8 @@ public final class Service {
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 @@ public final class Service {
/**
* 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 @@ public final class Service {
*
* @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 @@ public final class Service {
@Override
public int hashCode() {
return Objects.hash(serviceId);
return Objects.hash(id);
}
@Override
......@@ -110,18 +110,18 @@ public final class Service {
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)
......
......@@ -19,30 +19,33 @@ import com.google.common.base.MoreObjects;
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 @@ public final class ServiceId {
*
* @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 @@ public final class ServiceId {
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();
}
}
......
......@@ -277,11 +277,19 @@ public class CordVtn implements CordVtnService {
}
@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 @@ public class CordVtn implements CordVtnService {
}
/**
* 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
......
......@@ -67,18 +67,17 @@ public interface CordVtnService {
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);
}
......
/*
* Copyright 2015 Open Networking Laboratory
* 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.
......@@ -13,17 +13,19 @@
* 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;
import org.onlab.rest.AbstractWebApplication;
import java.util.Set;
@Component(immediate = true)
public class ApiDocRegistrator extends AbstractApiDocRegistrator {
public ApiDocRegistrator() {
super(new ApiDocProvider("/onos/cordvtn",
"CORD VTN Service REST API",
ApiDocRegistrator.class.getClassLoader()));
/**
* CORD VTN Web application.
*/
public class CordVtnWebApplication extends AbstractWebApplication {
@Override
public Set<Class<?>> getClasses() {
return getClasses(ServiceDependencyWebResource.class);
}
}
......
......@@ -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();
}
}
......
<?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>