blob: be8170253bc5bea72e4ae2a982c7d74bc637611e [file] [log] [blame]
/*
* 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.onosproject.pcerest;
import static javax.ws.rs.core.Response.Status.OK;
import static org.onlab.util.Tools.nullIsNotFound;
import java.util.Collection;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.LinkedList;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
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 com.google.common.collect.ImmutableList;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.intent.Constraint;
import org.onosproject.pce.pceservice.ExplicitPathInfo;
import org.onosproject.pce.pceservice.api.PceService;
import org.onosproject.pce.pceservice.PcePath;
import org.onosproject.pce.pceservice.DefaultPcePath;
import org.onosproject.pce.pceservice.LspType;
import org.onosproject.rest.AbstractWebResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Query and program pce path.
*/
@Path("path")
public class PcePathWebResource extends AbstractWebResource {
private final Logger log = LoggerFactory.getLogger(PcePathWebResource.class);
public static final String PCE_PATH_NOT_FOUND = "Path not found";
public static final String PCE_PATH_ID_EXIST = "Path exists";
public static final String PCE_PATH_ID_NOT_EXIST = "Path does not exist for the identifier";
public static final String PCE_SETUP_PATH_FAILED = "PCE Setup path has failed.";
/**
* Retrieve details of all paths created.
*
* @return 200 OK
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response queryAllPath() {
log.debug("Query all paths.");
PceService pceService = get(PceService.class);
Iterable<Tunnel> tunnels = pceService.queryAllPath();
ObjectNode result = mapper().createObjectNode();
ArrayNode pathEntry = result.putArray("paths");
if (tunnels != null) {
for (final Tunnel tunnel : tunnels) {
PcePath path = DefaultPcePath.builder().of(tunnel, pceService.explicitPathInfoList(tunnel
.tunnelName().value()))
.build();
pathEntry.add(codec(PcePath.class).encode(path, this));
}
}
return ok(result.toString()).build();
}
/**
* Retrieve details of a specified path id.
*
* @param id path id
* @return 200 OK, 404 if given identifier does not exist
*/
@GET
@Path("{path_id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response queryPath(@PathParam("path_id") String id) {
log.debug("Query path by identifier {}.", id);
PceService pceService = get(PceService.class);
Tunnel tunnel = nullIsNotFound(pceService.queryPath(TunnelId.valueOf(id)),
PCE_PATH_NOT_FOUND);
PcePath path = DefaultPcePath.builder().of(tunnel, pceService.explicitPathInfoList(tunnel
.tunnelName().value())).build();
if (path == null) {
return Response.status(OK).entity(PCE_SETUP_PATH_FAILED).build();
}
ObjectNode result = mapper().createObjectNode();
result.set("path", codec(PcePath.class).encode(path, this));
return ok(result.toString()).build();
}
/**
* Creates a new path.
*
* @param stream pce path from json
* @return status of the request
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response setupPath(InputStream stream) {
log.debug("Setup path.");
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode port = jsonTree.get("path");
TunnelService tunnelService = get(TunnelService.class);
PcePath path = codec(PcePath.class).decode((ObjectNode) port, this);
if (path == null) {
return Response.status(OK).entity(PCE_SETUP_PATH_FAILED).build();
}
//Validating tunnel name, duplicated tunnel names not allowed
Collection<Tunnel> existingTunnels = tunnelService.queryTunnel(Tunnel.Type.MPLS);
if (existingTunnels != null) {
for (Tunnel t : existingTunnels) {
if (t.tunnelName().toString().equals(path.name())) {
return Response.status(OK).entity(PCE_SETUP_PATH_FAILED).build();
}
}
}
DeviceId srcDevice = DeviceId.deviceId(path.source());
DeviceId dstDevice = DeviceId.deviceId(path.destination());
LspType lspType = path.lspType();
List<Constraint> listConstrnt = new LinkedList<Constraint>();
// Add bandwidth
listConstrnt.add(path.bandwidthConstraint());
// Add cost
listConstrnt.add(path.costConstraint());
List<ExplicitPathInfo> explicitPathInfoList = null;
if (path.explicitPathInfo() != null) {
explicitPathInfoList = ImmutableList.copyOf(path.explicitPathInfo());
}
Boolean issuccess = nullIsNotFound(get(PceService.class)
.setupPath(srcDevice, dstDevice, path.name(), listConstrnt,
lspType, explicitPathInfoList),
PCE_SETUP_PATH_FAILED);
return Response.status(OK).entity(issuccess.toString()).build();
} catch (IOException e) {
log.error("Exception while creating path {}.", e.toString());
throw new IllegalArgumentException(e);
}
}
/**
* Update details of a specified path id.
*
* @param id path id
* @param stream pce path from json
* @return 200 OK, 404 if given identifier does not exist
*/
@PUT
@Path("{path_id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response updatePath(@PathParam("path_id") String id,
final InputStream stream) {
log.debug("Update path by identifier {}.", id);
try {
ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
JsonNode pathNode = jsonTree.get("path");
PcePath path = codec(PcePath.class).decode((ObjectNode) pathNode, this);
if (path == null) {
return Response.status(OK).entity(PCE_SETUP_PATH_FAILED).build();
}
List<Constraint> constrntList = new LinkedList<Constraint>();
// Assign bandwidth
if (path.bandwidthConstraint() != null) {
constrntList.add(path.bandwidthConstraint());
}
// Assign cost
if (path.costConstraint() != null) {
constrntList.add(path.costConstraint());
}
Boolean result = nullIsNotFound(get(PceService.class).updatePath(TunnelId.valueOf(id), constrntList),
PCE_PATH_NOT_FOUND);
return Response.status(OK).entity(result.toString()).build();
} catch (IOException e) {
log.error("Update path failed because of exception {}.", e.toString());
throw new IllegalArgumentException(e);
}
}
/**
* Release a specified path.
*
* @param id path id
* @return 200 OK, 404 if given identifier does not exist
*/
@DELETE
@Path("{path_id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response releasePath(@PathParam("path_id") String id) {
log.debug("Deletes path by identifier {}.", id);
Boolean isSuccess = nullIsNotFound(get(PceService.class).releasePath(TunnelId.valueOf(id)),
PCE_PATH_NOT_FOUND);
if (!isSuccess) {
log.debug("Path identifier {} does not exist", id);
}
return Response.status(OK).entity(isSuccess.toString()).build();
}
}