org.onosproject.vtnweb.resources.RouterWebResource.java Source code

Java tutorial

Introduction

Here is the source code for org.onosproject.vtnweb.resources.RouterWebResource.java

Source

/*
 * 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 com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.onlab.packet.IpAddress;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.rest.AbstractWebResource;
import org.onosproject.vtnrsc.DefaultRouter;
import org.onosproject.vtnrsc.FixedIp;
import org.onosproject.vtnrsc.Router;
import org.onosproject.vtnrsc.Router.Status;
import org.onosproject.vtnrsc.RouterGateway;
import org.onosproject.vtnrsc.RouterId;
import org.onosproject.vtnrsc.RouterInterface;
import org.onosproject.vtnrsc.SubnetId;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.TenantNetworkId;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.router.RouterService;
import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
import org.onosproject.vtnweb.web.RouterCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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 java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.CREATED;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;

@Path("routers")
public class RouterWebResource extends AbstractWebResource {
    private final Logger log = LoggerFactory.getLogger(RouterWebResource.class);
    public static final String CREATE_FAIL = "Router is failed to create!";
    public static final String UPDATE_FAIL = "Router is failed to update!";
    public static final String GET_FAIL = "Router is failed to get!";
    public static final String NOT_EXIST = "Router does not exist!";
    public static final String DELETE_SUCCESS = "Router delete success!";
    public static final String JSON_NOT_NULL = "JsonNode can not be null";
    public static final String INTFACR_ADD_SUCCESS = "Interface add success";
    public static final String INTFACR_DEL_SUCCESS = "Interface delete success";

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response listRouters() {
        Collection<Router> routers = get(RouterService.class).getRouters();
        ObjectNode result = new ObjectMapper().createObjectNode();
        result.set("routers", new RouterCodec().encode(routers, this));
        return ok(result.toString()).build();
    }

    @GET
    @Path("{routerUUID}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response getRouter(@PathParam("routerUUID") String id, @QueryParam("fields") List<String> fields) {

        if (!get(RouterService.class).exists(RouterId.valueOf(id))) {
            return Response.status(NOT_FOUND).entity("The Router does not exists").build();
        }
        Router sub = nullIsNotFound(get(RouterService.class).getRouter(RouterId.valueOf(id)), NOT_EXIST);

        ObjectNode result = new ObjectMapper().createObjectNode();
        if (fields.size() > 0) {
            result.set("router", new RouterCodec().extracFields(sub, this, fields));
        } else {
            result.set("router", new RouterCodec().encode(sub, this));
        }
        return ok(result.toString()).build();
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createRouter(final InputStream input) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode subnode = mapper.readTree(input);
            Collection<Router> routers = createOrUpdateByInputStream(subnode);

            Boolean result = nullIsNotFound((get(RouterService.class).createRouters(routers)), CREATE_FAIL);
            if (!result) {
                return Response.status(CONFLICT).entity(CREATE_FAIL).build();
            }
            return Response.status(CREATED).entity(result.toString()).build();

        } catch (Exception e) {
            return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
        }
    }

    @PUT
    @Path("{routerUUID}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response updateRouter(@PathParam("routerUUID") String id, final InputStream input) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode subnode = mapper.readTree(input);
            Collection<Router> routers = changeUpdateJsonToSub(subnode, id);
            Boolean result = nullIsNotFound(get(RouterService.class).updateRouters(routers), UPDATE_FAIL);
            if (!result) {
                return Response.status(CONFLICT).entity(UPDATE_FAIL).build();
            }
            return ok(result.toString()).build();
        } catch (Exception e) {
            return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
        }
    }

    @DELETE
    @Path("{routerUUID}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response deleteSingleRouter(@PathParam("routerUUID") String id) throws IOException {
        try {
            RouterId routerId = RouterId.valueOf(id);
            Set<RouterId> routerIds = Sets.newHashSet(routerId);
            get(RouterService.class).removeRouters(routerIds);
            return Response.noContent().entity(DELETE_SUCCESS).build();
        } catch (Exception e) {
            return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
        }
    }

    @PUT
    @Path("{routerUUID}/add_router_interface")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addRouterInterface(@PathParam("routerUUID") String id, final InputStream input) {
        if (!get(RouterService.class).exists(RouterId.valueOf(id))) {
            return Response.status(NOT_FOUND).entity(NOT_EXIST).build();
        }
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode subnode = mapper.readTree(input);
            if (!subnode.hasNonNull("id")) {
                throw new IllegalArgumentException("id should not be null");
            } else if (subnode.get("id").asText().isEmpty()) {
                throw new IllegalArgumentException("id should not be empty");
            }
            RouterId routerId = RouterId.valueOf(id);
            if (!subnode.hasNonNull("subnet_id")) {
                throw new IllegalArgumentException("subnet_id should not be null");
            } else if (subnode.get("subnet_id").asText().isEmpty()) {
                throw new IllegalArgumentException("subnet_id should not be empty");
            }
            SubnetId subnetId = SubnetId.subnetId(subnode.get("subnet_id").asText());
            if (!subnode.hasNonNull("tenant_id")) {
                throw new IllegalArgumentException("tenant_id should not be null");
            } else if (subnode.get("tenant_id").asText().isEmpty()) {
                throw new IllegalArgumentException("tenant_id should not be empty");
            }
            TenantId tenentId = TenantId.tenantId(subnode.get("tenant_id").asText());
            if (!subnode.hasNonNull("port_id")) {
                throw new IllegalArgumentException("port_id should not be null");
            } else if (subnode.get("port_id").asText().isEmpty()) {
                throw new IllegalArgumentException("port_id should not be empty");
            }
            VirtualPortId portId = VirtualPortId.portId(subnode.get("port_id").asText());
            RouterInterface routerInterface = RouterInterface.routerInterface(subnetId, portId, routerId, tenentId);
            get(RouterInterfaceService.class).addRouterInterface(routerInterface);
            return ok(INTFACR_ADD_SUCCESS).build();
        } catch (Exception e) {
            return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
        }
    }

    @PUT
    @Path("{routerUUID}/remove_router_interface")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response removeRouterInterface(@PathParam("routerUUID") String id, final InputStream input) {
        if (!get(RouterService.class).exists(RouterId.valueOf(id))) {
            return Response.status(NOT_FOUND).entity(NOT_EXIST).build();
        }
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode subnode = mapper.readTree(input);
            if (!subnode.hasNonNull("id")) {
                throw new IllegalArgumentException("id should not be null");
            } else if (subnode.get("id").asText().isEmpty()) {
                throw new IllegalArgumentException("id should not be empty");
            }
            RouterId routerId = RouterId.valueOf(id);
            if (!subnode.hasNonNull("subnet_id")) {
                throw new IllegalArgumentException("subnet_id should not be null");
            } else if (subnode.get("subnet_id").asText().isEmpty()) {
                throw new IllegalArgumentException("subnet_id should not be empty");
            }
            SubnetId subnetId = SubnetId.subnetId(subnode.get("subnet_id").asText());
            if (!subnode.hasNonNull("port_id")) {
                throw new IllegalArgumentException("port_id should not be null");
            } else if (subnode.get("port_id").asText().isEmpty()) {
                throw new IllegalArgumentException("port_id should not be empty");
            }
            VirtualPortId portId = VirtualPortId.portId(subnode.get("port_id").asText());
            if (!subnode.hasNonNull("tenant_id")) {
                throw new IllegalArgumentException("tenant_id should not be null");
            } else if (subnode.get("tenant_id").asText().isEmpty()) {
                throw new IllegalArgumentException("tenant_id should not be empty");
            }
            TenantId tenentId = TenantId.tenantId(subnode.get("tenant_id").asText());
            RouterInterface routerInterface = RouterInterface.routerInterface(subnetId, portId, routerId, tenentId);
            get(RouterInterfaceService.class).removeRouterInterface(routerInterface);
            return ok(INTFACR_DEL_SUCCESS).build();
        } catch (Exception e) {
            return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
        }
    }

    private Collection<Router> createOrUpdateByInputStream(JsonNode subnode) throws Exception {
        checkNotNull(subnode, JSON_NOT_NULL);
        JsonNode routerNode = subnode.get("routers");
        if (routerNode == null) {
            routerNode = subnode.get("router");
        }
        log.debug("routerNode is {}", routerNode.toString());

        if (routerNode.isArray()) {
            throw new Exception("only singleton requests allowed");
        } else {
            return changeJsonToSub(routerNode);
        }
    }

    /**
     * Returns a collection of floatingIps from floatingIpNodes.
     *
     * @param routerNode the router json node
     * @return routers a collection of router
     * @throws Exception when any argument is illegal
     */
    public Collection<Router> changeJsonToSub(JsonNode routerNode) throws Exception {
        checkNotNull(routerNode, JSON_NOT_NULL);
        Map<RouterId, Router> subMap = new HashMap<RouterId, Router>();
        if (!routerNode.hasNonNull("id")) {
            new IllegalArgumentException("id should not be null");
        } else if (routerNode.get("id").asText().isEmpty()) {
            throw new IllegalArgumentException("id should not be empty");
        }
        RouterId id = RouterId.valueOf(routerNode.get("id").asText());

        if (!routerNode.hasNonNull("tenant_id")) {
            throw new IllegalArgumentException("tenant_id should not be null");
        } else if (routerNode.get("tenant_id").asText().isEmpty()) {
            throw new IllegalArgumentException("tenant_id should not be empty");
        }
        TenantId tenantId = TenantId.tenantId(routerNode.get("tenant_id").asText());

        VirtualPortId gwPortId = null;
        if (routerNode.hasNonNull("gw_port_id")) {
            gwPortId = VirtualPortId.portId(routerNode.get("gw_port_id").asText());
        }

        if (!routerNode.hasNonNull("status")) {
            throw new IllegalArgumentException("status should not be null");
        } else if (routerNode.get("status").asText().isEmpty()) {
            throw new IllegalArgumentException("status should not be empty");
        }
        Status status = Status.valueOf(routerNode.get("status").asText());

        String routerName = null;
        if (routerNode.hasNonNull("name")) {
            routerName = routerNode.get("name").asText();
        }

        boolean adminStateUp = true;
        checkArgument(routerNode.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
        if (routerNode.hasNonNull("admin_state_up")) {
            adminStateUp = routerNode.get("admin_state_up").asBoolean();
        }
        boolean distributed = false;
        if (routerNode.hasNonNull("distributed")) {
            distributed = routerNode.get("distributed").asBoolean();
        }
        RouterGateway gateway = null;
        if (routerNode.hasNonNull("external_gateway_info")) {
            gateway = jsonNodeToGateway(routerNode.get("external_gateway_info"));
        }
        List<String> routes = new ArrayList<String>();
        DefaultRouter routerObj = new DefaultRouter(id, routerName, adminStateUp, status, distributed, gateway,
                gwPortId, tenantId, routes);
        subMap.put(id, routerObj);
        return Collections.unmodifiableCollection(subMap.values());
    }

    /**
     * Returns a collection of floatingIps from floatingIpNodes.
     *
     * @param subnode the router json node
     * @param routerId the router identify
     * @return routers a collection of router
     * @throws Exception when any argument is illegal
     */
    public Collection<Router> changeUpdateJsonToSub(JsonNode subnode, String routerId) throws Exception {
        checkNotNull(subnode, JSON_NOT_NULL);
        checkNotNull(routerId, "routerId should not be null");
        Map<RouterId, Router> subMap = new HashMap<RouterId, Router>();
        JsonNode routerNode = subnode.get("router");
        RouterId id = RouterId.valueOf(routerId);
        Router sub = nullIsNotFound(get(RouterService.class).getRouter(id), NOT_EXIST);
        TenantId tenantId = sub.tenantId();

        VirtualPortId gwPortId = null;
        if (routerNode.hasNonNull("gw_port_id")) {
            gwPortId = VirtualPortId.portId(routerNode.get("gw_port_id").asText());
        }
        Status status = sub.status();

        String routerName = routerNode.get("name").asText();

        checkArgument(routerNode.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
        boolean adminStateUp = routerNode.get("admin_state_up").asBoolean();

        boolean distributed = sub.distributed();
        if (routerNode.hasNonNull("distributed")) {
            distributed = routerNode.get("distributed").asBoolean();
        }
        RouterGateway gateway = sub.externalGatewayInfo();
        if (routerNode.hasNonNull("external_gateway_info")) {
            gateway = jsonNodeToGateway(routerNode.get("external_gateway_info"));
        }
        List<String> routes = new ArrayList<String>();
        DefaultRouter routerObj = new DefaultRouter(id, routerName, adminStateUp, status, distributed, gateway,
                gwPortId, tenantId, routes);
        subMap.put(id, routerObj);
        return Collections.unmodifiableCollection(subMap.values());
    }

    /**
     * Changes JsonNode Gateway to the Gateway.
     *
     * @param gateway the gateway JsonNode
     * @return gateway
     */
    private RouterGateway jsonNodeToGateway(JsonNode gateway) {
        checkNotNull(gateway, JSON_NOT_NULL);
        if (!gateway.hasNonNull("network_id")) {
            throw new IllegalArgumentException("network_id should not be null");
        } else if (gateway.get("network_id").asText().isEmpty()) {
            throw new IllegalArgumentException("network_id should not be empty");
        }
        TenantNetworkId networkId = TenantNetworkId.networkId(gateway.get("network_id").asText());

        if (!gateway.hasNonNull("enable_snat")) {
            throw new IllegalArgumentException("enable_snat should not be null");
        } else if (gateway.get("enable_snat").asText().isEmpty()) {
            throw new IllegalArgumentException("enable_snat should not be empty");
        }
        checkArgument(gateway.get("enable_snat").isBoolean(), "enable_snat should be boolean");
        boolean enableSnat = gateway.get("enable_snat").asBoolean();

        if (!gateway.hasNonNull("external_fixed_ips")) {
            throw new IllegalArgumentException("external_fixed_ips should not be null");
        } else if (gateway.get("external_fixed_ips").isNull()) {
            throw new IllegalArgumentException("external_fixed_ips should not be empty");
        }
        Iterable<FixedIp> fixedIpList = jsonNodeToFixedIp(gateway.get("external_fixed_ips"));
        RouterGateway gatewayObj = RouterGateway.routerGateway(networkId, enableSnat, Sets.newHashSet(fixedIpList));
        return gatewayObj;
    }

    /**
     * Changes JsonNode fixedIp to a collection of the fixedIp.
     *
     * @param fixedIp the allocationPools JsonNode
     * @return a collection of fixedIp
     */
    private Iterable<FixedIp> jsonNodeToFixedIp(JsonNode fixedIp) {
        checkNotNull(fixedIp, JSON_NOT_NULL);
        ConcurrentMap<Integer, FixedIp> fixedIpMaps = Maps.newConcurrentMap();
        Integer i = 0;
        for (JsonNode node : fixedIp) {
            if (!node.hasNonNull("subnet_id")) {
                throw new IllegalArgumentException("subnet_id should not be null");
            } else if (node.get("subnet_id").asText().isEmpty()) {
                throw new IllegalArgumentException("subnet_id should not be empty");
            }
            SubnetId subnetId = SubnetId.subnetId(node.get("subnet_id").asText());
            if (!node.hasNonNull("ip_address")) {
                throw new IllegalArgumentException("ip_address should not be null");
            } else if (node.get("ip_address").asText().isEmpty()) {
                throw new IllegalArgumentException("ip_address should not be empty");
            }
            IpAddress ipAddress = IpAddress.valueOf(node.get("ip_address").asText());
            FixedIp fixedIpObj = FixedIp.fixedIp(subnetId, ipAddress);

            fixedIpMaps.putIfAbsent(i, fixedIpObj);
            i++;
        }
        return Collections.unmodifiableCollection(fixedIpMaps.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;
    }
}