blob: e958765389ac13f6b5c48d308487fddde64bd91d [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;
jiangrui9d54c262015-11-28 14:23:39 +080063
64@Path("floatingips")
65public class FloatingIpWebResource extends AbstractWebResource {
66 private final Logger log = LoggerFactory
67 .getLogger(FloatingIpWebResource.class);
68 public static final String CREATE_FAIL = "Floating IP is failed to create!";
69 public static final String UPDATE_FAIL = "Floating IP is failed to update!";
lishuaib43dbf72016-01-06 11:11:35 +080070 public static final String DELETE_FAIL = "Floating IP is failed to delete!";
jiangrui9d54c262015-11-28 14:23:39 +080071 public static final String GET_FAIL = "Floating IP is failed to get!";
72 public static final String NOT_EXIST = "Floating IP does not exist!";
73 public static final String DELETE_SUCCESS = "Floating IP delete success!";
74 public static final String JSON_NOT_NULL = "JsonNode can not be null";
75
76 @GET
77 @Produces(MediaType.APPLICATION_JSON)
Wu wenbind0b119f2016-05-11 18:03:41 +080078 @Consumes(MediaType.APPLICATION_JSON)
jiangrui9d54c262015-11-28 14:23:39 +080079 public Response listFloatingIps() {
80 Collection<FloatingIp> floatingIps = get(FloatingIpService.class)
81 .getFloatingIps();
82 ObjectNode result = new ObjectMapper().createObjectNode();
83 result.set("floatingips",
84 new FloatingIpCodec().encode(floatingIps, this));
85 return ok(result.toString()).build();
86 }
87
88 @GET
89 @Path("{floatingIpUUID}")
90 @Produces(MediaType.APPLICATION_JSON)
Wu wenbind0b119f2016-05-11 18:03:41 +080091 @Consumes(MediaType.APPLICATION_JSON)
jiangrui9d54c262015-11-28 14:23:39 +080092 public Response getFloatingIp(@PathParam("floatingIpUUID") String id,
93 @QueryParam("fields") List<String> fields) {
94
95 if (!get(FloatingIpService.class).exists(FloatingIpId.of(id))) {
96 return Response.status(NOT_FOUND).entity(NOT_EXIST).build();
97 }
98 FloatingIp sub = nullIsNotFound(get(FloatingIpService.class)
99 .getFloatingIp(FloatingIpId.of(id)), GET_FAIL);
100
101 ObjectNode result = new ObjectMapper().createObjectNode();
Jon Hallcbd1b392017-01-18 20:15:44 -0800102 if (!fields.isEmpty()) {
jiangrui9d54c262015-11-28 14:23:39 +0800103 result.set("floatingip",
104 new FloatingIpCodec().extracFields(sub, this, fields));
105 } else {
106 result.set("floatingip", new FloatingIpCodec().encode(sub, this));
107 }
108 return ok(result.toString()).build();
109 }
110
111 @POST
112 @Produces(MediaType.APPLICATION_JSON)
113 @Consumes(MediaType.APPLICATION_JSON)
114 public Response createFloatingIp(final InputStream input) {
115 try {
116 ObjectMapper mapper = new ObjectMapper();
117 JsonNode subnode = mapper.readTree(input);
118 Collection<FloatingIp> floatingIps = createOrUpdateByInputStream(subnode);
119 Boolean result = nullIsNotFound((get(FloatingIpService.class)
120 .createFloatingIps(floatingIps)),
121 CREATE_FAIL);
122 if (!result) {
123 return Response.status(CONFLICT).entity(CREATE_FAIL).build();
124 }
125 return Response.status(CREATED).entity(result.toString()).build();
126
127 } catch (Exception e) {
128 return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
129 }
130 }
131
132 @PUT
133 @Path("{floatingIpUUID}")
134 @Produces(MediaType.APPLICATION_JSON)
135 @Consumes(MediaType.APPLICATION_JSON)
136 public Response updateFloatingIp(@PathParam("floatingIpUUID") String id,
137 final InputStream input) {
138 try {
139 ObjectMapper mapper = new ObjectMapper();
140 JsonNode subnode = mapper.readTree(input);
141 Collection<FloatingIp> floatingIps = createOrUpdateByInputStream(subnode);
142 Boolean result = nullIsNotFound(get(FloatingIpService.class)
143 .updateFloatingIps(floatingIps), UPDATE_FAIL);
144 if (!result) {
145 return Response.status(CONFLICT).entity(UPDATE_FAIL).build();
146 }
147 return ok(result.toString()).build();
148 } catch (Exception e) {
149 return Response.status(BAD_REQUEST).entity(e.getMessage()).build();
150 }
151 }
152
jiangrui9d54c262015-11-28 14:23:39 +0800153 @DELETE
Wu wenbinb0bd6132016-05-10 19:20:23 +0800154 @Path("{floatingIpUUID}")
155 @Consumes(MediaType.APPLICATION_JSON)
156 @Produces(MediaType.APPLICATION_JSON)
jiangrui9d54c262015-11-28 14:23:39 +0800157 public Response deleteSingleFloatingIp(@PathParam("floatingIpUUID") String id)
158 throws IOException {
159 try {
160 FloatingIpId floatingIpId = FloatingIpId.of(id);
161 Set<FloatingIpId> floatingIpIds = Sets.newHashSet(floatingIpId);
lishuaib43dbf72016-01-06 11:11:35 +0800162 Boolean result = nullIsNotFound(get(FloatingIpService.class)
163 .removeFloatingIps(floatingIpIds), DELETE_FAIL);
164 if (!result) {
165 return Response.status(CONFLICT).entity(DELETE_FAIL).build();
166 }
Jian Lic2a542b2016-05-10 11:48:19 -0700167 return Response.noContent().entity(DELETE_SUCCESS).build();
jiangrui9d54c262015-11-28 14:23:39 +0800168 } catch (Exception e) {
169 return Response.status(NOT_FOUND).entity(e.getMessage()).build();
170 }
171 }
172
173 private Collection<FloatingIp> createOrUpdateByInputStream(JsonNode subnode)
174 throws Exception {
175 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
Bharat saraswald270b182015-12-01 01:53:06 +0530196 * @throws Exception when any argument is illegal
jiangrui9d54c262015-11-28 14:23:39 +0800197 */
198 public Collection<FloatingIp> changeJsonToSub(JsonNode floatingIpNodes)
199 throws Exception {
200 checkNotNull(floatingIpNodes, JSON_NOT_NULL);
201 Map<FloatingIpId, FloatingIp> subMap = new HashMap<FloatingIpId, FloatingIp>();
202 if (!floatingIpNodes.hasNonNull("id")) {
203 throw new IllegalArgumentException("id should not be null");
204 } else if (floatingIpNodes.get("id").asText().isEmpty()) {
205 throw new IllegalArgumentException("id should not be empty");
206 }
207 FloatingIpId id = FloatingIpId.of(floatingIpNodes.get("id")
208 .asText());
209
210 if (!floatingIpNodes.hasNonNull("tenant_id")) {
211 throw new IllegalArgumentException("tenant_id should not be null");
212 } else if (floatingIpNodes.get("tenant_id").asText().isEmpty()) {
213 throw new IllegalArgumentException("tenant_id should not be empty");
214 }
215 TenantId tenantId = TenantId.tenantId(floatingIpNodes.get("tenant_id")
216 .asText());
217
218 if (!floatingIpNodes.hasNonNull("floating_network_id")) {
219 throw new IllegalArgumentException(
220 "floating_network_id should not be null");
221 } else if (floatingIpNodes.get("floating_network_id").asText()
222 .isEmpty()) {
223 throw new IllegalArgumentException(
224 "floating_network_id should not be empty");
225 }
226 TenantNetworkId networkId = TenantNetworkId.networkId(floatingIpNodes
227 .get("floating_network_id").asText());
228
229 VirtualPortId portId = null;
230 if (floatingIpNodes.hasNonNull("port_id")) {
231 portId = VirtualPortId.portId(floatingIpNodes.get("port_id")
232 .asText());
233 }
234
235 RouterId routerId = null;
236 if (floatingIpNodes.hasNonNull("router_id")) {
237 routerId = RouterId.valueOf(floatingIpNodes.get("router_id")
238 .asText());
239 }
240
241 IpAddress fixedIp = null;
242 if (floatingIpNodes.hasNonNull("fixed_ip_address")) {
243 fixedIp = IpAddress.valueOf(floatingIpNodes.get("fixed_ip_address")
244 .asText());
245 }
246
247 if (!floatingIpNodes.hasNonNull("floating_ip_address")) {
248 throw new IllegalArgumentException(
249 "floating_ip_address should not be null");
250 } else if (floatingIpNodes.get("floating_ip_address").asText()
251 .isEmpty()) {
252 throw new IllegalArgumentException(
253 "floating_ip_address should not be empty");
254 }
255 IpAddress floatingIp = IpAddress.valueOf(floatingIpNodes
256 .get("floating_ip_address").asText());
257
258 if (!floatingIpNodes.hasNonNull("status")) {
259 throw new IllegalArgumentException("status should not be null");
260 } else if (floatingIpNodes.get("status").asText().isEmpty()) {
261 throw new IllegalArgumentException("status should not be empty");
262 }
263 Status status = Status.valueOf(floatingIpNodes.get("status").asText());
264
265 DefaultFloatingIp floatingIpObj = new DefaultFloatingIp(id, tenantId,
266 networkId,
267 portId,
268 routerId,
269 floatingIp,
270 fixedIp, status);
271 subMap.put(id, floatingIpObj);
272 return Collections.unmodifiableCollection(subMap.values());
273 }
274
275 /**
276 * Returns the specified item if that items is null; otherwise throws not
277 * found exception.
278 *
279 * @param item item to check
280 * @param <T> item type
281 * @param message not found message
282 * @return item if not null
283 * @throws org.onlab.util.ItemNotFoundException if item is null
284 */
285 protected <T> T nullIsNotFound(T item, String message) {
286 if (item == null) {
287 throw new ItemNotFoundException(message);
288 }
289 return item;
290 }
291}