blob: 56066ab171b46572e962ecefe9ae76dd51656008 [file] [log] [blame]
jiangrui9d54c262015-11-28 14:23:39 +08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
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
18import static com.google.common.base.Preconditions.checkNotNull;
19import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
20import static javax.ws.rs.core.Response.Status.NOT_FOUND;
21import static javax.ws.rs.core.Response.Status.CREATED;
22import static javax.ws.rs.core.Response.Status.CONFLICT;
23import static javax.ws.rs.core.Response.Status.NO_CONTENT;
24
25import java.io.IOException;
26import java.io.InputStream;
27import java.util.Collection;
28import java.util.Collections;
29import java.util.HashMap;
30import java.util.List;
31import java.util.Map;
32import java.util.Set;
33
34import javax.ws.rs.Consumes;
35import javax.ws.rs.DELETE;
36import javax.ws.rs.GET;
37import javax.ws.rs.POST;
38import javax.ws.rs.PUT;
39import javax.ws.rs.Path;
40import javax.ws.rs.PathParam;
41import javax.ws.rs.Produces;
42import javax.ws.rs.QueryParam;
43import javax.ws.rs.core.MediaType;
44import javax.ws.rs.core.Response;
45
46import org.onlab.packet.IpAddress;
47import org.onlab.util.ItemNotFoundException;
48import org.onosproject.rest.AbstractWebResource;
49import org.onosproject.vtnrsc.DefaultFloatingIp;
50import org.onosproject.vtnrsc.FloatingIp;
51import org.onosproject.vtnrsc.FloatingIpId;
52import org.onosproject.vtnrsc.TenantId;
53import org.onosproject.vtnrsc.TenantNetworkId;
54import org.onosproject.vtnrsc.VirtualPortId;
55import org.onosproject.vtnrsc.RouterId;
56import org.onosproject.vtnrsc.FloatingIp.Status;
57import org.onosproject.vtnrsc.floatingip.FloatingIpService;
58import org.onosproject.vtnweb.web.FloatingIpCodec;
59import org.slf4j.Logger;
60import org.slf4j.LoggerFactory;
61
62import com.fasterxml.jackson.databind.JsonNode;
63import com.fasterxml.jackson.databind.ObjectMapper;
64import com.fasterxml.jackson.databind.node.ObjectNode;
65import com.google.common.collect.Sets;
66
67@Path("floatingips")
68public class FloatingIpWebResource extends AbstractWebResource {
69 private final Logger log = LoggerFactory
70 .getLogger(FloatingIpWebResource.class);
71 public static final String CREATE_FAIL = "Floating IP is failed to create!";
72 public static final String UPDATE_FAIL = "Floating IP is failed to update!";
lishuaib43dbf72016-01-06 11:11:35 +080073 public static final String DELETE_FAIL = "Floating IP is failed to delete!";
jiangrui9d54c262015-11-28 14:23:39 +080074 public static final String GET_FAIL = "Floating IP is failed to get!";
75 public static final String NOT_EXIST = "Floating IP does not exist!";
76 public static final String DELETE_SUCCESS = "Floating IP delete success!";
77 public static final String JSON_NOT_NULL = "JsonNode can not be null";
78
79 @GET
80 @Produces(MediaType.APPLICATION_JSON)
81 public Response listFloatingIps() {
82 Collection<FloatingIp> floatingIps = get(FloatingIpService.class)
83 .getFloatingIps();
84 ObjectNode result = new ObjectMapper().createObjectNode();
85 result.set("floatingips",
86 new FloatingIpCodec().encode(floatingIps, this));
87 return ok(result.toString()).build();
88 }
89
90 @GET
91 @Path("{floatingIpUUID}")
92 @Produces(MediaType.APPLICATION_JSON)
93 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();
103 if (fields.size() > 0) {
104 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();
118 JsonNode subnode = mapper.readTree(input);
119 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();
141 JsonNode subnode = mapper.readTree(input);
142 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
154 @Path("{floatingIpUUID}")
155 @DELETE
156 public Response deleteSingleFloatingIp(@PathParam("floatingIpUUID") String id)
157 throws IOException {
158 try {
159 FloatingIpId floatingIpId = FloatingIpId.of(id);
160 Set<FloatingIpId> floatingIpIds = Sets.newHashSet(floatingIpId);
lishuaib43dbf72016-01-06 11:11:35 +0800161 Boolean result = nullIsNotFound(get(FloatingIpService.class)
162 .removeFloatingIps(floatingIpIds), DELETE_FAIL);
163 if (!result) {
164 return Response.status(CONFLICT).entity(DELETE_FAIL).build();
165 }
jiangrui9d54c262015-11-28 14:23:39 +0800166 return Response.status(NO_CONTENT).entity(DELETE_SUCCESS).build();
167 } catch (Exception e) {
168 return Response.status(NOT_FOUND).entity(e.getMessage()).build();
169 }
170 }
171
172 private Collection<FloatingIp> createOrUpdateByInputStream(JsonNode subnode)
173 throws Exception {
174 checkNotNull(subnode, JSON_NOT_NULL);
175 Collection<FloatingIp> floatingIps = null;
176 JsonNode floatingIpNodes = subnode.get("floatingips");
177 if (floatingIpNodes == null) {
178 floatingIpNodes = subnode.get("floatingip");
179 }
180 log.debug("floatingNodes is {}", floatingIpNodes.toString());
181
182 if (floatingIpNodes.isArray()) {
183 throw new IllegalArgumentException("only singleton requests allowed");
184 } else {
185 floatingIps = changeJsonToSub(floatingIpNodes);
186 }
187 return floatingIps;
188 }
189
190 /**
191 * Returns a collection of floatingIps from floatingIpNodes.
192 *
193 * @param floatingIpNodes the floatingIp json node
194 * @return floatingIps a collection of floatingIp
Bharat saraswald270b182015-12-01 01:53:06 +0530195 * @throws Exception when any argument is illegal
jiangrui9d54c262015-11-28 14:23:39 +0800196 */
197 public Collection<FloatingIp> changeJsonToSub(JsonNode floatingIpNodes)
198 throws Exception {
199 checkNotNull(floatingIpNodes, JSON_NOT_NULL);
200 Map<FloatingIpId, FloatingIp> subMap = new HashMap<FloatingIpId, FloatingIp>();
201 if (!floatingIpNodes.hasNonNull("id")) {
202 throw new IllegalArgumentException("id should not be null");
203 } else if (floatingIpNodes.get("id").asText().isEmpty()) {
204 throw new IllegalArgumentException("id should not be empty");
205 }
206 FloatingIpId id = FloatingIpId.of(floatingIpNodes.get("id")
207 .asText());
208
209 if (!floatingIpNodes.hasNonNull("tenant_id")) {
210 throw new IllegalArgumentException("tenant_id should not be null");
211 } else if (floatingIpNodes.get("tenant_id").asText().isEmpty()) {
212 throw new IllegalArgumentException("tenant_id should not be empty");
213 }
214 TenantId tenantId = TenantId.tenantId(floatingIpNodes.get("tenant_id")
215 .asText());
216
217 if (!floatingIpNodes.hasNonNull("floating_network_id")) {
218 throw new IllegalArgumentException(
219 "floating_network_id should not be null");
220 } else if (floatingIpNodes.get("floating_network_id").asText()
221 .isEmpty()) {
222 throw new IllegalArgumentException(
223 "floating_network_id should not be empty");
224 }
225 TenantNetworkId networkId = TenantNetworkId.networkId(floatingIpNodes
226 .get("floating_network_id").asText());
227
228 VirtualPortId portId = null;
229 if (floatingIpNodes.hasNonNull("port_id")) {
230 portId = VirtualPortId.portId(floatingIpNodes.get("port_id")
231 .asText());
232 }
233
234 RouterId routerId = null;
235 if (floatingIpNodes.hasNonNull("router_id")) {
236 routerId = RouterId.valueOf(floatingIpNodes.get("router_id")
237 .asText());
238 }
239
240 IpAddress fixedIp = null;
241 if (floatingIpNodes.hasNonNull("fixed_ip_address")) {
242 fixedIp = IpAddress.valueOf(floatingIpNodes.get("fixed_ip_address")
243 .asText());
244 }
245
246 if (!floatingIpNodes.hasNonNull("floating_ip_address")) {
247 throw new IllegalArgumentException(
248 "floating_ip_address should not be null");
249 } else if (floatingIpNodes.get("floating_ip_address").asText()
250 .isEmpty()) {
251 throw new IllegalArgumentException(
252 "floating_ip_address should not be empty");
253 }
254 IpAddress floatingIp = IpAddress.valueOf(floatingIpNodes
255 .get("floating_ip_address").asText());
256
257 if (!floatingIpNodes.hasNonNull("status")) {
258 throw new IllegalArgumentException("status should not be null");
259 } else if (floatingIpNodes.get("status").asText().isEmpty()) {
260 throw new IllegalArgumentException("status should not be empty");
261 }
262 Status status = Status.valueOf(floatingIpNodes.get("status").asText());
263
264 DefaultFloatingIp floatingIpObj = new DefaultFloatingIp(id, tenantId,
265 networkId,
266 portId,
267 routerId,
268 floatingIp,
269 fixedIp, status);
270 subMap.put(id, floatingIpObj);
271 return Collections.unmodifiableCollection(subMap.values());
272 }
273
274 /**
275 * Returns the specified item if that items is null; otherwise throws not
276 * found exception.
277 *
278 * @param item item to check
279 * @param <T> item type
280 * @param message not found message
281 * @return item if not null
282 * @throws org.onlab.util.ItemNotFoundException if item is null
283 */
284 protected <T> T nullIsNotFound(T item, String message) {
285 if (item == null) {
286 throw new ItemNotFoundException(message);
287 }
288 return item;
289 }
290}