blob: 9fc25a856efd815be420d67d4dcf77ba7bb3db20 [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 Milkey86ee5e82018-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 Milkey86ee5e82018-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 Milkey86ee5e82018-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
Ray Milkey2b4958a2018-02-06 18:59:06 -0800174 private Collection<FloatingIp> createOrUpdateByInputStream(JsonNode subnode) {
jiangrui9d54c262015-11-28 14:23:39 +0800175 checkNotNull(subnode, JSON_NOT_NULL);
176 Collection<FloatingIp> floatingIps = null;
177 JsonNode floatingIpNodes = subnode.get("floatingips");
178 if (floatingIpNodes == null) {
179 floatingIpNodes = subnode.get("floatingip");
180 }
181 log.debug("floatingNodes is {}", floatingIpNodes.toString());
182
183 if (floatingIpNodes.isArray()) {
184 throw new IllegalArgumentException("only singleton requests allowed");
185 } else {
186 floatingIps = changeJsonToSub(floatingIpNodes);
187 }
188 return floatingIps;
189 }
190
191 /**
192 * Returns a collection of floatingIps from floatingIpNodes.
193 *
194 * @param floatingIpNodes the floatingIp json node
195 * @return floatingIps a collection of floatingIp
jiangrui9d54c262015-11-28 14:23:39 +0800196 */
Ray Milkey986a47a2018-01-25 11:38:51 -0800197 public Collection<FloatingIp> changeJsonToSub(JsonNode floatingIpNodes) {
jiangrui9d54c262015-11-28 14:23:39 +0800198 checkNotNull(floatingIpNodes, JSON_NOT_NULL);
199 Map<FloatingIpId, FloatingIp> subMap = new HashMap<FloatingIpId, FloatingIp>();
200 if (!floatingIpNodes.hasNonNull("id")) {
201 throw new IllegalArgumentException("id should not be null");
202 } else if (floatingIpNodes.get("id").asText().isEmpty()) {
203 throw new IllegalArgumentException("id should not be empty");
204 }
205 FloatingIpId id = FloatingIpId.of(floatingIpNodes.get("id")
206 .asText());
207
208 if (!floatingIpNodes.hasNonNull("tenant_id")) {
209 throw new IllegalArgumentException("tenant_id should not be null");
210 } else if (floatingIpNodes.get("tenant_id").asText().isEmpty()) {
211 throw new IllegalArgumentException("tenant_id should not be empty");
212 }
213 TenantId tenantId = TenantId.tenantId(floatingIpNodes.get("tenant_id")
214 .asText());
215
216 if (!floatingIpNodes.hasNonNull("floating_network_id")) {
217 throw new IllegalArgumentException(
218 "floating_network_id should not be null");
219 } else if (floatingIpNodes.get("floating_network_id").asText()
220 .isEmpty()) {
221 throw new IllegalArgumentException(
222 "floating_network_id should not be empty");
223 }
224 TenantNetworkId networkId = TenantNetworkId.networkId(floatingIpNodes
225 .get("floating_network_id").asText());
226
227 VirtualPortId portId = null;
228 if (floatingIpNodes.hasNonNull("port_id")) {
229 portId = VirtualPortId.portId(floatingIpNodes.get("port_id")
230 .asText());
231 }
232
233 RouterId routerId = null;
234 if (floatingIpNodes.hasNonNull("router_id")) {
235 routerId = RouterId.valueOf(floatingIpNodes.get("router_id")
236 .asText());
237 }
238
239 IpAddress fixedIp = null;
240 if (floatingIpNodes.hasNonNull("fixed_ip_address")) {
241 fixedIp = IpAddress.valueOf(floatingIpNodes.get("fixed_ip_address")
242 .asText());
243 }
244
245 if (!floatingIpNodes.hasNonNull("floating_ip_address")) {
246 throw new IllegalArgumentException(
247 "floating_ip_address should not be null");
248 } else if (floatingIpNodes.get("floating_ip_address").asText()
249 .isEmpty()) {
250 throw new IllegalArgumentException(
251 "floating_ip_address should not be empty");
252 }
253 IpAddress floatingIp = IpAddress.valueOf(floatingIpNodes
254 .get("floating_ip_address").asText());
255
256 if (!floatingIpNodes.hasNonNull("status")) {
257 throw new IllegalArgumentException("status should not be null");
258 } else if (floatingIpNodes.get("status").asText().isEmpty()) {
259 throw new IllegalArgumentException("status should not be empty");
260 }
261 Status status = Status.valueOf(floatingIpNodes.get("status").asText());
262
263 DefaultFloatingIp floatingIpObj = new DefaultFloatingIp(id, tenantId,
264 networkId,
265 portId,
266 routerId,
267 floatingIp,
268 fixedIp, status);
269 subMap.put(id, floatingIpObj);
270 return Collections.unmodifiableCollection(subMap.values());
271 }
272
273 /**
274 * Returns the specified item if that items is null; otherwise throws not
275 * found exception.
276 *
277 * @param item item to check
278 * @param <T> item type
279 * @param message not found message
280 * @return item if not null
281 * @throws org.onlab.util.ItemNotFoundException if item is null
282 */
283 protected <T> T nullIsNotFound(T item, String message) {
284 if (item == null) {
285 throw new ItemNotFoundException(message);
286 }
287 return item;
288 }
289}