blob: fc7ee655dede07787ce53fe93c2df793c14a1f0c [file] [log] [blame]
Hyunsun Moonb6febbe2016-02-12 15:59:53 -08001/*
Brian O'Connor8e57fd52016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Hyunsun Moonb6febbe2016-02-12 15:59:53 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
alshabibb4d31712016-06-01 18:51:03 -070016package org.opencord.cordvtn.rest;
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080017
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070018import com.fasterxml.jackson.databind.JsonNode;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070019import org.onlab.osgi.DefaultServiceDirectory;
Hyunsun Moon187bf532017-01-19 10:57:40 +090020import org.onlab.packet.IpAddress;
21import org.onlab.packet.IpPrefix;
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080022import org.onosproject.rest.AbstractWebResource;
Hyunsun Moon187bf532017-01-19 10:57:40 +090023import org.opencord.cordvtn.api.core.ServiceNetworkAdminService;
24import org.opencord.cordvtn.api.net.NetworkId;
25import org.opencord.cordvtn.api.net.ServiceNetwork;
26import org.opencord.cordvtn.impl.DefaultServiceNetwork;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070027import org.openstack4j.core.transport.ObjectMapperSingleton;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070028import org.openstack4j.openstack.networking.domain.NeutronSubnet;
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080029import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import javax.ws.rs.Consumes;
33import javax.ws.rs.DELETE;
34import javax.ws.rs.POST;
35import javax.ws.rs.PUT;
36import javax.ws.rs.Path;
37import javax.ws.rs.PathParam;
38import javax.ws.rs.Produces;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070039import javax.ws.rs.core.Context;
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080040import javax.ws.rs.core.MediaType;
41import javax.ws.rs.core.Response;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070042import javax.ws.rs.core.UriBuilder;
43import javax.ws.rs.core.UriInfo;
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080044import java.io.InputStream;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070045
46import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
Hyunsun Moon187bf532017-01-19 10:57:40 +090047import static javax.ws.rs.core.Response.Status.OK;
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070048import static javax.ws.rs.core.Response.created;
49import static javax.ws.rs.core.Response.noContent;
50import static javax.ws.rs.core.Response.status;
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080051
52/**
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070053 * Neutron ML2 mechanism driver implementation for the subnet resource.
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080054 */
55@Path("subnets")
56public class NeutronMl2SubnetsWebResource extends AbstractWebResource {
57 protected final Logger log = LoggerFactory.getLogger(getClass());
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080058
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070059 private static final String MESSAGE = "Received subnets %s request";
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070060 private static final String SUBNETS = "subnets";
61
Hyunsun Moon187bf532017-01-19 10:57:40 +090062 private final ServiceNetworkAdminService adminService =
63 DefaultServiceDirectory.getService(ServiceNetworkAdminService.class);
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070064
65 @Context
66 private UriInfo uriInfo;
67
68 /**
69 * Creates a subnet from the JSON input stream.
70 *
71 * @param input subnet JSON input stream
72 * @return 201 CREATED if the JSON is correct, 400 BAD_REQUEST if the JSON
73 * is invalid or duplicated subnet already exists
74 */
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080075 @POST
76 @Consumes(MediaType.APPLICATION_JSON)
77 @Produces(MediaType.APPLICATION_JSON)
78 public Response createSubnet(InputStream input) {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070079 log.trace(String.format(MESSAGE, "CREATE"));
80
Hyunsun Moon187bf532017-01-19 10:57:40 +090081 // FIXME do not allow more than one subnet per network
82 final ServiceNetwork snet = readSubnet(input);
83 adminService.updateServiceNetwork(snet);
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070084 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
85 .path(SUBNETS)
Hyunsun Moon187bf532017-01-19 10:57:40 +090086 .path(snet.id().id());
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070087
Hyunsun Moon187bf532017-01-19 10:57:40 +090088 // TODO fix Neutron networking-onos to send Network UPDATE when subnet created
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070089 return created(locationBuilder.build()).build();
Hyunsun Moonb6febbe2016-02-12 15:59:53 -080090 }
91
Hyunsun Mooneaf75e62016-09-27 16:40:23 -070092 /**
93 * Updates the subnet with the specified identifier.
94 *
95 * @param id subnet identifier
96 * @param input subnet JSON input stream
97 * @return 200 OK with the updated subnet, 400 BAD_REQUEST if the requested
98 * subnet does not exist
99 */
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800100 @PUT
101 @Path("{id}")
102 @Produces(MediaType.APPLICATION_JSON)
103 @Consumes(MediaType.APPLICATION_JSON)
104 public Response updateSubnet(@PathParam("id") String id, InputStream input) {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700105 log.trace(String.format(MESSAGE, "UPDATE " + id));
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800106
Hyunsun Moon187bf532017-01-19 10:57:40 +0900107 final ServiceNetwork snet = readSubnet(input);
108 adminService.updateServiceNetwork(snet);
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700109
Hyunsun Moon187bf532017-01-19 10:57:40 +0900110 return status(OK).build();
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700111 }
112
113 /**
114 * Removes the subnet.
115 *
116 * @param id subnet identifier
117 * @return 204 NO_CONTENT, 400 BAD_REQUEST if the subnet does not exist
118 */
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800119 @DELETE
120 @Path("{id}")
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700121 @Consumes(MediaType.APPLICATION_JSON)
122 @Produces(MediaType.APPLICATION_JSON)
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800123 public Response deleteSubnet(@PathParam("id") String id) {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700124 log.trace(String.format(MESSAGE, "DELETE " + id));
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700125 return noContent().build();
126 }
127
Hyunsun Moon187bf532017-01-19 10:57:40 +0900128 private ServiceNetwork readSubnet(InputStream input) {
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700129 try {
130 JsonNode jsonTree = mapper().enable(INDENT_OUTPUT).readTree(input);
131 log.trace(mapper().writeValueAsString(jsonTree));
Hyunsun Moon187bf532017-01-19 10:57:40 +0900132 NeutronSubnet osSubnet = ObjectMapperSingleton.getContext(NeutronSubnet.class)
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700133 .readerFor(NeutronSubnet.class)
134 .readValue(jsonTree);
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700135
Hyunsun Moon187bf532017-01-19 10:57:40 +0900136 return DefaultServiceNetwork.builder()
137 .id(NetworkId.of(osSubnet.getNetworkId()))
138 .subnet(IpPrefix.valueOf(osSubnet.getCidr()))
139 .serviceIp(IpAddress.valueOf(osSubnet.getGateway()))
140 .build();
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700141 } catch (Exception e) {
Hyunsun Moon187bf532017-01-19 10:57:40 +0900142 throw new IllegalArgumentException(e);
Hyunsun Mooneaf75e62016-09-27 16:40:23 -0700143 }
Hyunsun Moonb6febbe2016-02-12 15:59:53 -0800144 }
145}