/* * 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.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 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 networks = get(TenantNetworkService.class) .getNetworks(); Iterator 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 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 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 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 changeJson2obj(String flag, TenantNetworkId networkId, JsonNode node) { checkNotNull(node, JSON_NOT_NULL); TenantNetwork network = null; ConcurrentMap 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 changeJson2objs(JsonNode nodes) { checkNotNull(nodes, JSON_NOT_NULL); TenantNetwork network = null; ConcurrentMap 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 item type * @param message not found message * @return item if not null * @throws org.onlab.util.ItemNotFoundException if item is null */ protected T nullIsNotFound(T item, String message) { if (item == null) { throw new ItemNotFoundException(message); } return item; } }