blob: 380e4ad05ab201e369289a03017cb54c71e83d75 [file] [log] [blame]
/*
* Copyright 2015-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.vtnweb.resources;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static javax.ws.rs.core.Response.Status.OK;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
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.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.DefaultTenantNetwork;
import org.onosproject.vtnrsc.PhysicalNetwork;
import org.onosproject.vtnrsc.SegmentationId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetwork;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.TenantNetwork.State;
import org.onosproject.vtnrsc.TenantNetwork.Type;
import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
import org.onosproject.vtnweb.web.TenantNetworkCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
/**
* REST resource for interacting with the inventory of networks.
*/
@Path("networks")
public class TenantNetworkWebResource extends AbstractWebResource {
public static final String NETWORK_NOT_FOUND = "Network is not found";
public static final String NETWORK_ID_EXIST = "Network id is existed";
public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";
public static final String CREATE_NETWORK = "create network";
public static final String UPDATE_NETWORK = "update network";
public static final String DELETE_NETWORK = "delete network";
public static final String JSON_NOT_NULL = "JsonNode can not be null";
protected static final Logger log = LoggerFactory
.getLogger(TenantNetworkWebResource.class);
private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
.newConcurrentMap();
@GET
@Produces({ MediaType.APPLICATION_JSON })
public Response getNetworks(@QueryParam("id") String queryId,
@QueryParam("name") String queryName,
@QueryParam("admin_state_up") String queryadminStateUp,
@QueryParam("status") String querystate,
@QueryParam("shared") String queryshared,
@QueryParam("tenant_id") String querytenantId,
@QueryParam("router:external") String routerExternal,
@QueryParam("provider:network_type") String type,
@QueryParam("provider:physical_network") String physicalNetwork,
@QueryParam("provider:segmentation_id") String segmentationId) {
Iterable<TenantNetwork> networks = get(TenantNetworkService.class)
.getNetworks();
Iterator<TenantNetwork> networkors = networks.iterator();
while (networkors.hasNext()) {
TenantNetwork network = networkors.next();
if ((queryId == null || queryId.equals(network.id().toString()))
&& (queryName == null || queryName.equals(network.name()))
&& (queryadminStateUp == null || queryadminStateUp
.equals(Boolean.toString(network.adminStateUp())))
&& (querystate == null || querystate.equals(network.state()
.toString()))
&& (queryshared == null || queryshared.equals(Boolean.toString(network
.shared())))
&& (querytenantId == null || querytenantId.equals(network
.tenantId().toString()))
&& (routerExternal == null || routerExternal.equals(Boolean.toString(network
.routerExternal())))
&& (type == null || type.equals(network.type().toString()))
&& (physicalNetwork == null || physicalNetwork
.equals(network.physicalNetwork().toString()))
&& (segmentationId == null || segmentationId.equals(network
.segmentationId().toString()))) {
networksMap.putIfAbsent(network.id(), network);
}
}
networks = Collections.unmodifiableCollection(networksMap.values());
ObjectNode result = new ObjectMapper().createObjectNode();
result.set("networks", new TenantNetworkCodec().encode(networks, this));
return ok(result.toString()).build();
}
private State isState(String state) {
if (state.equals("ACTIVE")) {
return TenantNetwork.State.ACTIVE;
} else if (state.equals("BUILD")) {
return TenantNetwork.State.BUILD;
} else if (state.equals("DOWN")) {
return TenantNetwork.State.DOWN;
} else if (state.equals("ERROR")) {
return TenantNetwork.State.ERROR;
} else {
return null;
}
}
private Type isType(String type) {
if (type.equals("LOCAL")) {
return TenantNetwork.Type.LOCAL;
} else {
return null;
}
}
@GET
@Path("{id}")
@Produces({ MediaType.APPLICATION_JSON })
public Response getNetwork(@PathParam("id") String id) {
if (!get(TenantNetworkService.class).exists(TenantNetworkId
.networkId(id))) {
return Response.status(NOT_FOUND)
.entity(NETWORK_NOT_FOUND).build();
}
TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)
.getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);
ObjectNode result = new ObjectMapper().createObjectNode();
result.set("network", new TenantNetworkCodec().encode(network, this));
return ok(result.toString()).build();
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response createNetworks(InputStream input) {
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonNode nodes = null;
Iterable<TenantNetwork> networks = null;
if (cfg.get("network") != null) {
nodes = cfg.get("network");
if (nodes.isArray()) {
networks = changeJson2objs(nodes);
} else {
networks = changeJson2obj(CREATE_NETWORK, null, nodes);
}
} else if (cfg.get("networks") != null) {
nodes = cfg.get("networks");
networks = changeJson2objs(nodes);
}
Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
.createNetworks(networks)),
NETWORK_NOT_FOUND);
if (!issuccess) {
return Response.status(INTERNAL_SERVER_ERROR)
.entity(NETWORK_ID_EXIST).build();
}
return Response.status(OK).entity(issuccess.toString()).build();
} catch (Exception e) {
log.error("Creates tenantNetwork exception {}.", e.toString());
return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
.build();
}
}
@PUT
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response updateNetworks(@PathParam("id") String id, InputStream input) {
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode cfg = mapper.readTree(input);
JsonNode nodes = null;
Iterable<TenantNetwork> networks = null;
if (cfg.get("network") != null) {
nodes = cfg.get("network");
if (nodes.isArray()) {
networks = changeJson2objs(nodes);
} else {
networks = changeJson2obj(UPDATE_NETWORK,
TenantNetworkId.networkId(id),
nodes);
}
} else if (cfg.get("networks") != null) {
nodes = cfg.get("networks");
networks = changeJson2objs(nodes);
}
Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
.updateNetworks(networks)),
NETWORK_NOT_FOUND);
if (!issuccess) {
return Response.status(INTERNAL_SERVER_ERROR)
.entity(NETWORK_ID_NOT_EXIST).build();
}
return Response.status(OK).entity(issuccess.toString()).build();
} catch (Exception e) {
log.error("Updates tenantNetwork failed because of exception {}.",
e.toString());
return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
.build();
}
}
@DELETE
@Path("{id}")
public Response deleteNetworks(@PathParam("id") String id) {
log.debug("Deletes network by identifier {}.", id);
Set<TenantNetworkId> networkSet = new HashSet<>();
networkSet.add(TenantNetworkId.networkId(id));
Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)
.removeNetworks(networkSet), NETWORK_NOT_FOUND);
if (!issuccess) {
log.debug("Network identifier {} is not existed", id);
return Response.status(INTERNAL_SERVER_ERROR)
.entity(NETWORK_ID_NOT_EXIST).build();
}
return Response.status(OK).entity(issuccess.toString()).build();
}
/**
* Returns a collection of tenantNetworks.
*
* @param flag the flag
* @param networkId network identifier
* @param node the network json node
* @return a collection of tenantNetworks
*/
public Iterable<TenantNetwork> changeJson2obj(String flag,
TenantNetworkId networkId,
JsonNode node) {
checkNotNull(node, JSON_NOT_NULL);
TenantNetwork network = null;
ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
.newConcurrentMap();
checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
checkArgument(node.get("shared").isBoolean(), "shared should be boolean");
checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean");
String name = node.get("name").asText();
boolean adminStateUp = node.get("admin_state_up").asBoolean();
String state = node.get("status").asText();
boolean shared = node.get("shared").asBoolean();
String tenantId = node.get("tenant_id").asText();
boolean routerExternal = node.get("router:external").asBoolean();
String type = node.get("provider:network_type").asText();
String physicalNetwork = node.get("provider:physical_network").asText();
String segmentationId = node.get("provider:segmentation_id").asText();
TenantNetworkId id = null;
if (flag.equals(CREATE_NETWORK)) {
id = TenantNetworkId.networkId(node.get("id").asText());
} else if (flag.equals(UPDATE_NETWORK)) {
id = networkId;
}
network = new DefaultTenantNetwork(
id,
name,
adminStateUp,
isState(state),
shared,
TenantId.tenantId(tenantId),
routerExternal,
isType(type),
PhysicalNetwork
.physicalNetwork(physicalNetwork),
SegmentationId
.segmentationId(segmentationId));
networksMap.putIfAbsent(id, network);
return Collections.unmodifiableCollection(networksMap.values());
}
/**
* Returns a collection of tenantNetworks.
*
* @param nodes the network jsonnodes
* @return a collection of tenantNetworks
*/
public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {
checkNotNull(nodes, JSON_NOT_NULL);
TenantNetwork network = null;
ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
.newConcurrentMap();
for (JsonNode node : nodes) {
String id = node.get("id").asText();
String name = node.get("name").asText();
boolean adminStateUp = node.get("admin_state_up").asBoolean();
String state = node.get("status").asText();
boolean shared = node.get("shared").asBoolean();
String tenantId = node.get("tenant_id").asText();
boolean routerExternal = node.get("router:external")
.asBoolean();
String type = node.get("provider:network_type").asText();
String physicalNetwork = node.get("provider:physical_network").asText();
String segmentationId = node.get("provider:segmentation_id").asText();
network = new DefaultTenantNetwork(
TenantNetworkId.networkId(id),
name,
adminStateUp,
isState(state),
shared,
TenantId.tenantId(tenantId),
routerExternal,
isType(type),
PhysicalNetwork.physicalNetwork(physicalNetwork),
SegmentationId.segmentationId(segmentationId));
networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);
}
return Collections.unmodifiableCollection(networksMap.values());
}
/**
* Returns the specified item if that items is null; otherwise throws not
* found exception.
*
* @param item item to check
* @param <T> item type
* @param message not found message
* @return item if not null
* @throws org.onlab.util.ItemNotFoundException if item is null
*/
protected <T> T nullIsNotFound(T item, String message) {
if (item == null) {
throw new ItemNotFoundException(message);
}
return item;
}
}