blob: 67af86e103b12b5d0484d2f38cb9c00357b3e989 [file] [log] [blame]
jiangrui9d54c262015-11-28 14:23:39 +08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
jiangrui9d54c262015-11-28 14:23:39 +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 */
16package org.onosproject.vtnweb.resources;
17
Jian Lic2a542b2016-05-10 11:48:19 -070018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.collect.Sets;
22import org.onlab.packet.IpAddress;
23import org.onlab.util.ItemNotFoundException;
24import org.onosproject.rest.AbstractWebResource;
25import org.onosproject.vtnrsc.DefaultFloatingIp;
26import org.onosproject.vtnrsc.FloatingIp;
27import org.onosproject.vtnrsc.FloatingIp.Status;
28import org.onosproject.vtnrsc.FloatingIpId;
29import org.onosproject.vtnrsc.RouterId;
30import org.onosproject.vtnrsc.TenantId;
31import org.onosproject.vtnrsc.TenantNetworkId;
32import org.onosproject.vtnrsc.VirtualPortId;
33import org.onosproject.vtnrsc.floatingip.FloatingIpService;
34import org.onosproject.vtnweb.web.FloatingIpCodec;
35import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
jiangrui9d54c262015-11-28 14:23:39 +080037
38import javax.ws.rs.Consumes;
39import javax.ws.rs.DELETE;
40import javax.ws.rs.GET;
41import javax.ws.rs.POST;
42import javax.ws.rs.PUT;
43import javax.ws.rs.Path;
44import javax.ws.rs.PathParam;
45import javax.ws.rs.Produces;
46import javax.ws.rs.QueryParam;
47import javax.ws.rs.core.MediaType;
48import javax.ws.rs.core.Response;
Jian Lic2a542b2016-05-10 11:48:19 -070049import java.io.IOException;
50import java.io.InputStream;
51import java.util.Collection;
52import java.util.Collections;
53import java.util.HashMap;
54import java.util.List;
55import java.util.Map;
56import java.util.Set;
jiangrui9d54c262015-11-28 14:23:39 +080057
Jian Lic2a542b2016-05-10 11:48:19 -070058import static com.google.common.base.Preconditions.checkNotNull;
59import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
60import static javax.ws.rs.core.Response.Status.CONFLICT;
61import static javax.ws.rs.core.Response.Status.CREATED;
62import static javax.ws.rs.core.Response.Status.NOT_FOUND;
Ray Milkeyb784adb2018-04-02 15:33:07 -070063import static org.onlab.util.Tools.readTreeFromStream;
jiangrui9d54c262015-11-28 14:23:39 +080064
65@Path("floatingips")
66public class FloatingIpWebResource extends AbstractWebResource {
67 private final Logger log = LoggerFactory
68 .getLogger(FloatingIpWebResource.class);
69 public static final String CREATE_FAIL = "Floating IP is failed to create!";
70 public static final String UPDATE_FAIL = "Floating IP is failed to update!";
lishuaib43dbf72016-01-06 11:11:35 +080071 public static final String DELETE_FAIL = "Floating IP is failed to delete!";
jiangrui9d54c262015-11-28 14:23:39 +080072 public static final String GET_FAIL = "Floating IP is failed to get!";
73 public static final String NOT_EXIST = "Floating IP does not exist!";
74 public static final String DELETE_SUCCESS = "Floating IP delete success!";
75 public static final String JSON_NOT_NULL = "JsonNode can not be null";
76
77 @GET
78 @Produces(MediaType.APPLICATION_JSON)
Wu wenbind0b119f2016-05-11 18:03:41 +080079 @Consumes(MediaType.APPLICATION_JSON)
jiangrui9d54c262015-11-28 14:23:39 +080080 public Response listFloatingIps() {
81 Collection<FloatingIp> floatingIps = get(FloatingIpService.class)
82 .getFloatingIps();
83 ObjectNode result = new ObjectMapper().createObjectNode();
84 result.set("floatingips",
85 new FloatingIpCodec().encode(floatingIps, this));
86 return ok(result.toString()).build();
87 }
88
89 @GET
90 @Path("{floatingIpUUID}")
91 @Produces(MediaType.APPLICATION_JSON)
Wu wenbind0b119f2016-05-11 18:03:41 +080092 @Consumes(MediaType.APPLICATION_JSON)
jiangrui9d54c262015-11-28 14:23:39 +080093 public Response getFloatingIp(@PathParam("floatingIpUUID") String id,
94 @QueryParam("fields") List<String> fields) {
95
96 if (!get(FloatingIpService.class).exists(FloatingIpId.of(id))) {
97 return Response.status(NOT_FOUND).entity(NOT_EXIST).build();
98 }
99 FloatingIp sub = nullIsNotFound(get(FloatingIpService.class)
100 .getFloatingIp(FloatingIpId.of(id)), GET_FAIL);
101
102 ObjectNode result = new ObjectMapper().createObjectNode();
Jon Hallcbd1b392017-01-18 20:15:44 -0800103 if (!fields.isEmpty()) {
jiangrui9d54c262015-11-28 14:23:39 +0800104 result.set("floatingip",
105 new FloatingIpCodec().extracFields(sub, this, fields));
106 } else {
107 result.set("floatingip", new FloatingIpCodec().encode(sub, this));
108 }
109 return ok(result.toString()).build();
110 }
111
112 @POST
113 @Produces(MediaType.APPLICATION_JSON)
114 @Consumes(MediaType.APPLICATION_JSON)
115 public Response createFloatingIp(final InputStream input) {
116 try {
117 ObjectMapper mapper = new ObjectMapper();
Ray Milkeyb784adb2018-04-02 15:33:07 -0700118 JsonNode subnode = readTreeFromStream(mapper, input);
jiangrui9d54c262015-11-28 14:23:39 +0800119 Collection<FloatingIp> floatingIps = createOrUpdateByInputStream(subnode);
120 Boolean result = nullIsNotFound((get(FloatingIpService.class)
121 .createFloatingIps(floatingIps)),
122 CREATE_FAIL);
123 if (!result) {
124 return Response.status(CONFLICT).entity(CREATE_FAIL).build();
125 }
126 return Response.status(CREATED).entity(result.toString()).build();
127
128 } catch (Exception e) {
129 return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
130 }
131 }
132
133 @PUT
134 @Path("{floatingIpUUID}")
135 @Produces(MediaType.APPLICATION_JSON)
136 @Consumes(MediaType.APPLICATION_JSON)
137 public Response updateFloatingIp(@PathParam("floatingIpUUID") String id,
138 final InputStream input) {
139 try {
140 ObjectMapper mapper = new ObjectMapper();
Ray Milkeyb784adb2018-04-02 15:33:07 -0700141 JsonNode subnode = readTreeFromStream(mapper, input);
jiangrui9d54c262015-11-28 14:23:39 +0800142 Collection<FloatingIp> floatingIps = createOrUpdateByInputStream(subnode);
143 Boolean result = nullIsNotFound(get(FloatingIpService.class)
144 .updateFloatingIps(floatingIps), UPDATE_FAIL);
145 if (!result) {
146 return Response.status(CONFLICT).entity(UPDATE_FAIL).build();
147 }
148 return ok(result.toString()).build();
149 } catch (Exception e) {
150 return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
151 }
152 }
153
jiangrui9d54c262015-11-28 14:23:39 +0800154 @DELETE
Wu wenbinb0bd6132016-05-10 19:20:23 +0800155 @Path("{floatingIpUUID}")
156 @Consumes(MediaType.APPLICATION_JSON)
157 @Produces(MediaType.APPLICATION_JSON)
jiangrui9d54c262015-11-28 14:23:39 +0800158 public Response deleteSingleFloatingIp(@PathParam("floatingIpUUID") String id)
159 throws IOException {
160 try {
161 FloatingIpId floatingIpId = FloatingIpId.of(id);
162 Set<FloatingIpId> floatingIpIds = Sets.newHashSet(floatingIpId);
lishuaib43dbf72016-01-06 11:11:35 +0800163 Boolean result = nullIsNotFound(get(FloatingIpService.class)
164 .removeFloatingIps(floatingIpIds), DELETE_FAIL);
165 if (!result) {
166 return Response.status(CONFLICT).entity(DELETE_FAIL).build();
167 }
Jian Lic2a542b2016-05-10 11:48:19 -0700168 return Response.noContent().entity(DELETE_SUCCESS).build();
jiangrui9d54c262015-11-28 14:23:39 +0800169 } catch (Exception e) {
170 return Response.status(NOT_FOUND).entity(e.getMessage()).build();
171 }
172 }
173
174 private Collection<FloatingIp> createOrUpdateByInputStream(JsonNode subnode)
175 throws Exception {
176 checkNotNull(subnode, JSON_NOT_NULL);
177 Collection<FloatingIp> floatingIps = null;
178 JsonNode floatingIpNodes = subnode.get("floatingips");
179 if (floatingIpNodes == null) {
180 floatingIpNodes = subnode.get("floatingip");
181 }
182 log.debug("floatingNodes is {}", floatingIpNodes.toString());
183
184 if (floatingIpNodes.isArray()) {
185 throw new IllegalArgumentException("only singleton requests allowed");
186 } else {
187 floatingIps = changeJsonToSub(floatingIpNodes);
188 }
189 return floatingIps;
190 }
191
192 /**
193 * Returns a collection of floatingIps from floatingIpNodes.
194 *
195 * @param floatingIpNodes the floatingIp json node
196 * @return floatingIps a collection of floatingIp
Bharat saraswald270b182015-12-01 01:53:06 +0530197 * @throws Exception when any argument is illegal
jiangrui9d54c262015-11-28 14:23:39 +0800198 */
199 public Collection<FloatingIp> changeJsonToSub(JsonNode floatingIpNodes)
200 throws Exception {
201 checkNotNull(floatingIpNodes, JSON_NOT_NULL);
202 Map<FloatingIpId, FloatingIp> subMap = new HashMap<FloatingIpId, FloatingIp>();
203 if (!floatingIpNodes.hasNonNull("id")) {
204 throw new IllegalArgumentException("id should not be null");
205 } else if (floatingIpNodes.get("id").asText().isEmpty()) {
206 throw new IllegalArgumentException("id should not be empty");
207 }
208 FloatingIpId id = FloatingIpId.of(floatingIpNodes.get("id")
209 .asText());
210
211 if (!floatingIpNodes.hasNonNull("tenant_id")) {
212 throw new IllegalArgumentException("tenant_id should not be null");
213 } else if (floatingIpNodes.get("tenant_id").asText().isEmpty()) {
214 throw new IllegalArgumentException("tenant_id should not be empty");
215 }
216 TenantId tenantId = TenantId.tenantId(floatingIpNodes.get("tenant_id")
217 .asText());
218
219 if (!floatingIpNodes.hasNonNull("floating_network_id")) {
220 throw new IllegalArgumentException(
221 "floating_network_id should not be null");
222 } else if (floatingIpNodes.get("floating_network_id").asText()
223 .isEmpty()) {
224 throw new IllegalArgumentException(
225 "floating_network_id should not be empty");
226 }
227 TenantNetworkId networkId = TenantNetworkId.networkId(floatingIpNodes
228 .get("floating_network_id").asText());
229
230 VirtualPortId portId = null;
231 if (floatingIpNodes.hasNonNull("port_id")) {
232 portId = VirtualPortId.portId(floatingIpNodes.get("port_id")
233 .asText());
234 }
235
236 RouterId routerId = null;
237 if (floatingIpNodes.hasNonNull("router_id")) {
238 routerId = RouterId.valueOf(floatingIpNodes.get("router_id")
239 .asText());
240 }
241
242 IpAddress fixedIp = null;
243 if (floatingIpNodes.hasNonNull("fixed_ip_address")) {
244 fixedIp = IpAddress.valueOf(floatingIpNodes.get("fixed_ip_address")
245 .asText());
246 }
247
248 if (!floatingIpNodes.hasNonNull("floating_ip_address")) {
249 throw new IllegalArgumentException(
250 "floating_ip_address should not be null");
251 } else if (floatingIpNodes.get("floating_ip_address").asText()
252 .isEmpty()) {
253 throw new IllegalArgumentException(
254 "floating_ip_address should not be empty");
255 }
256 IpAddress floatingIp = IpAddress.valueOf(floatingIpNodes
257 .get("floating_ip_address").asText());
258
259 if (!floatingIpNodes.hasNonNull("status")) {
260 throw new IllegalArgumentException("status should not be null");
261 } else if (floatingIpNodes.get("status").asText().isEmpty()) {
262 throw new IllegalArgumentException("status should not be empty");
263 }
264 Status status = Status.valueOf(floatingIpNodes.get("status").asText());
265
266 DefaultFloatingIp floatingIpObj = new DefaultFloatingIp(id, tenantId,
267 networkId,
268 portId,
269 routerId,
270 floatingIp,
271 fixedIp, status);
272 subMap.put(id, floatingIpObj);
273 return Collections.unmodifiableCollection(subMap.values());
274 }
275
276 /**
277 * Returns the specified item if that items is null; otherwise throws not
278 * found exception.
279 *
280 * @param item item to check
281 * @param <T> item type
282 * @param message not found message
283 * @return item if not null
284 * @throws org.onlab.util.ItemNotFoundException if item is null
285 */
286 protected <T> T nullIsNotFound(T item, String message) {
287 if (item == null) {
288 throw new ItemNotFoundException(message);
289 }
290 return item;
291 }
292}