blob: a18682c2b5a7e7bdf99a4cb1b1312145da00eaaf [file] [log] [blame]
Madan Jampani38a88212015-09-15 11:21:27 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Madan Jampani38a88212015-09-15 11:21:27 -07003 *
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.Maps;
22import org.onlab.util.ItemNotFoundException;
23import org.onosproject.rest.AbstractWebResource;
24import org.onosproject.vtnrsc.DefaultTenantNetwork;
25import org.onosproject.vtnrsc.PhysicalNetwork;
26import org.onosproject.vtnrsc.SegmentationId;
27import org.onosproject.vtnrsc.TenantId;
28import org.onosproject.vtnrsc.TenantNetwork;
29import org.onosproject.vtnrsc.TenantNetwork.State;
30import org.onosproject.vtnrsc.TenantNetwork.Type;
31import org.onosproject.vtnrsc.TenantNetworkId;
lishuai38eeac42016-05-19 15:34:30 +080032import org.onosproject.vtnrsc.service.VtnRscService;
Jian Lic2a542b2016-05-10 11:48:19 -070033import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
34import org.onosproject.vtnweb.web.TenantNetworkCodec;
35import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
Madan Jampani38a88212015-09-15 11:21:27 -070037
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.InputStream;
50import java.util.Collections;
51import java.util.HashSet;
52import java.util.Iterator;
53import java.util.Set;
54import java.util.concurrent.ConcurrentMap;
Madan Jampani38a88212015-09-15 11:21:27 -070055
Jian Lic2a542b2016-05-10 11:48:19 -070056import static com.google.common.base.Preconditions.checkArgument;
57import static com.google.common.base.Preconditions.checkNotNull;
58import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
59import static javax.ws.rs.core.Response.Status.NOT_FOUND;
60import static javax.ws.rs.core.Response.Status.OK;
Ray Milkey86ee5e82018-04-02 15:33:07 -070061import static org.onlab.util.Tools.readTreeFromStream;
Madan Jampani38a88212015-09-15 11:21:27 -070062
63/**
64 * REST resource for interacting with the inventory of networks.
65 */
66@Path("networks")
67public class TenantNetworkWebResource extends AbstractWebResource {
68 public static final String NETWORK_NOT_FOUND = "Network is not found";
69 public static final String NETWORK_ID_EXIST = "Network id is existed";
70 public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";
71 public static final String CREATE_NETWORK = "create network";
72 public static final String UPDATE_NETWORK = "update network";
73 public static final String DELETE_NETWORK = "delete network";
74 public static final String JSON_NOT_NULL = "JsonNode can not be null";
75
Ray Milkey9c9cde42018-01-12 14:22:06 -080076 private static final Logger log = LoggerFactory
Madan Jampani38a88212015-09-15 11:21:27 -070077 .getLogger(TenantNetworkWebResource.class);
78 private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
79 .newConcurrentMap();
80
81 @GET
Wu wenbind0b119f2016-05-11 18:03:41 +080082 @Produces(MediaType.APPLICATION_JSON)
83 @Consumes(MediaType.APPLICATION_JSON)
Madan Jampani38a88212015-09-15 11:21:27 -070084 public Response getNetworks(@QueryParam("id") String queryId,
85 @QueryParam("name") String queryName,
86 @QueryParam("admin_state_up") String queryadminStateUp,
87 @QueryParam("status") String querystate,
88 @QueryParam("shared") String queryshared,
89 @QueryParam("tenant_id") String querytenantId,
90 @QueryParam("router:external") String routerExternal,
91 @QueryParam("provider:network_type") String type,
92 @QueryParam("provider:physical_network") String physicalNetwork,
93 @QueryParam("provider:segmentation_id") String segmentationId) {
94 Iterable<TenantNetwork> networks = get(TenantNetworkService.class)
95 .getNetworks();
96 Iterator<TenantNetwork> networkors = networks.iterator();
97 while (networkors.hasNext()) {
98 TenantNetwork network = networkors.next();
99 if ((queryId == null || queryId.equals(network.id().toString()))
100 && (queryName == null || queryName.equals(network.name()))
101 && (queryadminStateUp == null || queryadminStateUp
Satish K32035572015-11-22 14:49:14 +0530102 .equals(Boolean.toString(network.adminStateUp())))
Madan Jampani38a88212015-09-15 11:21:27 -0700103 && (querystate == null || querystate.equals(network.state()
104 .toString()))
Satish K32035572015-11-22 14:49:14 +0530105 && (queryshared == null || queryshared.equals(Boolean.toString(network
106 .shared())))
Madan Jampani38a88212015-09-15 11:21:27 -0700107 && (querytenantId == null || querytenantId.equals(network
108 .tenantId().toString()))
Satish K32035572015-11-22 14:49:14 +0530109 && (routerExternal == null || routerExternal.equals(Boolean.toString(network
110 .routerExternal())))
111 && (type == null || type.equals(network.type().toString()))
Madan Jampani38a88212015-09-15 11:21:27 -0700112 && (physicalNetwork == null || physicalNetwork
Satish K32035572015-11-22 14:49:14 +0530113 .equals(network.physicalNetwork().toString()))
Madan Jampani38a88212015-09-15 11:21:27 -0700114 && (segmentationId == null || segmentationId.equals(network
Satish K32035572015-11-22 14:49:14 +0530115 .segmentationId().toString()))) {
Madan Jampani38a88212015-09-15 11:21:27 -0700116 networksMap.putIfAbsent(network.id(), network);
117 }
118 }
119 networks = Collections.unmodifiableCollection(networksMap.values());
120 ObjectNode result = new ObjectMapper().createObjectNode();
121 result.set("networks", new TenantNetworkCodec().encode(networks, this));
122
123 return ok(result.toString()).build();
124 }
125
126 private State isState(String state) {
Jon Halla3fcf672017-03-28 16:53:22 -0700127 if ("ACTIVE".equals(state)) {
Madan Jampani38a88212015-09-15 11:21:27 -0700128 return TenantNetwork.State.ACTIVE;
Jon Halla3fcf672017-03-28 16:53:22 -0700129 } else if ("BUILD".equals(state)) {
Madan Jampani38a88212015-09-15 11:21:27 -0700130 return TenantNetwork.State.BUILD;
Jon Halla3fcf672017-03-28 16:53:22 -0700131 } else if ("DOWN".equals(state)) {
Madan Jampani38a88212015-09-15 11:21:27 -0700132 return TenantNetwork.State.DOWN;
Jon Halla3fcf672017-03-28 16:53:22 -0700133 } else if ("ERROR".equals(state)) {
Madan Jampani38a88212015-09-15 11:21:27 -0700134 return TenantNetwork.State.ERROR;
135 } else {
136 return null;
137 }
138 }
139
140 private Type isType(String type) {
Jon Halla3fcf672017-03-28 16:53:22 -0700141 if ("LOCAL".equals(type)) {
Madan Jampani38a88212015-09-15 11:21:27 -0700142 return TenantNetwork.Type.LOCAL;
143 } else {
144 return null;
145 }
146 }
147
148 @GET
149 @Path("{id}")
Wu wenbind0b119f2016-05-11 18:03:41 +0800150 @Produces(MediaType.APPLICATION_JSON)
151 @Consumes(MediaType.APPLICATION_JSON)
Madan Jampani38a88212015-09-15 11:21:27 -0700152 public Response getNetwork(@PathParam("id") String id) {
153
154 if (!get(TenantNetworkService.class).exists(TenantNetworkId
155 .networkId(id))) {
lishuai0f47f342015-09-16 11:38:48 +0800156 return Response.status(NOT_FOUND)
157 .entity(NETWORK_NOT_FOUND).build();
Madan Jampani38a88212015-09-15 11:21:27 -0700158 }
159 TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)
160 .getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);
161 ObjectNode result = new ObjectMapper().createObjectNode();
162 result.set("network", new TenantNetworkCodec().encode(network, this));
163
164 return ok(result.toString()).build();
165
166 }
167
168 @POST
169 @Produces(MediaType.APPLICATION_JSON)
170 @Consumes(MediaType.APPLICATION_JSON)
171 public Response createNetworks(InputStream input) {
172 try {
173 ObjectMapper mapper = new ObjectMapper();
Ray Milkey86ee5e82018-04-02 15:33:07 -0700174 JsonNode cfg = readTreeFromStream(mapper, input);
Madan Jampani38a88212015-09-15 11:21:27 -0700175 JsonNode nodes = null;
176 Iterable<TenantNetwork> networks = null;
177 if (cfg.get("network") != null) {
178 nodes = cfg.get("network");
179 if (nodes.isArray()) {
180 networks = changeJson2objs(nodes);
181 } else {
182 networks = changeJson2obj(CREATE_NETWORK, null, nodes);
183 }
184 } else if (cfg.get("networks") != null) {
185 nodes = cfg.get("networks");
186 networks = changeJson2objs(nodes);
187 }
188 Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
189 .createNetworks(networks)),
190 NETWORK_NOT_FOUND);
191
192 if (!issuccess) {
193 return Response.status(INTERNAL_SERVER_ERROR)
194 .entity(NETWORK_ID_EXIST).build();
195 }
196 return Response.status(OK).entity(issuccess.toString()).build();
197 } catch (Exception e) {
198 log.error("Creates tenantNetwork exception {}.", e.toString());
199 return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
200 .build();
201 }
202 }
203
204 @PUT
205 @Path("{id}")
206 @Produces(MediaType.APPLICATION_JSON)
207 @Consumes(MediaType.APPLICATION_JSON)
208 public Response updateNetworks(@PathParam("id") String id, InputStream input) {
209 try {
210 ObjectMapper mapper = new ObjectMapper();
Ray Milkey86ee5e82018-04-02 15:33:07 -0700211 JsonNode cfg = readTreeFromStream(mapper, input);
Madan Jampani38a88212015-09-15 11:21:27 -0700212 JsonNode nodes = null;
213 Iterable<TenantNetwork> networks = null;
214 if (cfg.get("network") != null) {
215 nodes = cfg.get("network");
216 if (nodes.isArray()) {
217 networks = changeJson2objs(nodes);
218 } else {
219 networks = changeJson2obj(UPDATE_NETWORK,
220 TenantNetworkId.networkId(id),
221 nodes);
222 }
223 } else if (cfg.get("networks") != null) {
224 nodes = cfg.get("networks");
225 networks = changeJson2objs(nodes);
226 }
227 Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
228 .updateNetworks(networks)),
229 NETWORK_NOT_FOUND);
230 if (!issuccess) {
231 return Response.status(INTERNAL_SERVER_ERROR)
232 .entity(NETWORK_ID_NOT_EXIST).build();
233 }
234 return Response.status(OK).entity(issuccess.toString()).build();
235 } catch (Exception e) {
236 log.error("Updates tenantNetwork failed because of exception {}.",
237 e.toString());
238 return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
239 .build();
240 }
241 }
242
243 @DELETE
244 @Path("{id}")
Wu wenbinb0bd6132016-05-10 19:20:23 +0800245 @Consumes(MediaType.APPLICATION_JSON)
246 @Produces(MediaType.APPLICATION_JSON)
Madan Jampani38a88212015-09-15 11:21:27 -0700247 public Response deleteNetworks(@PathParam("id") String id) {
248 log.debug("Deletes network by identifier {}.", id);
249 Set<TenantNetworkId> networkSet = new HashSet<>();
250 networkSet.add(TenantNetworkId.networkId(id));
251 Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)
252 .removeNetworks(networkSet), NETWORK_NOT_FOUND);
253 if (!issuccess) {
254 log.debug("Network identifier {} is not existed", id);
255 return Response.status(INTERNAL_SERVER_ERROR)
256 .entity(NETWORK_ID_NOT_EXIST).build();
257 }
Jian Lic2a542b2016-05-10 11:48:19 -0700258 return ok(issuccess.toString()).build();
Madan Jampani38a88212015-09-15 11:21:27 -0700259 }
260
261 /**
262 * Returns a collection of tenantNetworks.
263 *
264 * @param flag the flag
265 * @param networkId network identifier
266 * @param node the network json node
267 * @return a collection of tenantNetworks
268 */
269 public Iterable<TenantNetwork> changeJson2obj(String flag,
270 TenantNetworkId networkId,
271 JsonNode node) {
272 checkNotNull(node, JSON_NOT_NULL);
273 TenantNetwork network = null;
274 ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
275 .newConcurrentMap();
Satish Kab54ffa2015-11-27 14:19:42 +0530276 checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
277 checkArgument(node.get("shared").isBoolean(), "shared should be boolean");
278 checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean");
279 String name = node.get("name").asText();
280 boolean adminStateUp = node.get("admin_state_up").asBoolean();
281 String state = node.get("status").asText();
282 boolean shared = node.get("shared").asBoolean();
lishuai38eeac42016-05-19 15:34:30 +0800283 String tenantIdStr = node.get("tenant_id").asText();
Satish Kab54ffa2015-11-27 14:19:42 +0530284 boolean routerExternal = node.get("router:external").asBoolean();
285 String type = node.get("provider:network_type").asText();
286 String physicalNetwork = node.get("provider:physical_network").asText();
lishuai38eeac42016-05-19 15:34:30 +0800287 String segmentationIdStr = node.get("provider:segmentation_id").asText();
288 SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdStr);
289 TenantId tenantId = TenantId.tenantId(tenantIdStr);
Jon Halla3fcf672017-03-28 16:53:22 -0700290 if (segmentationIdStr == null || "null".equals(segmentationIdStr)) {
lishuai38eeac42016-05-19 15:34:30 +0800291 segmentationId = get(VtnRscService.class).getL3vni(tenantId);
292 }
Satish Kab54ffa2015-11-27 14:19:42 +0530293 TenantNetworkId id = null;
294 if (flag.equals(CREATE_NETWORK)) {
295 id = TenantNetworkId.networkId(node.get("id").asText());
296 } else if (flag.equals(UPDATE_NETWORK)) {
297 id = networkId;
Madan Jampani38a88212015-09-15 11:21:27 -0700298 }
Satish Kab54ffa2015-11-27 14:19:42 +0530299 network = new DefaultTenantNetwork(
300 id,
301 name,
302 adminStateUp,
303 isState(state),
304 shared,
lishuai38eeac42016-05-19 15:34:30 +0800305 tenantId,
Satish Kab54ffa2015-11-27 14:19:42 +0530306 routerExternal,
307 isType(type),
308 PhysicalNetwork
309 .physicalNetwork(physicalNetwork),
lishuai38eeac42016-05-19 15:34:30 +0800310 segmentationId);
Satish Kab54ffa2015-11-27 14:19:42 +0530311 networksMap.putIfAbsent(id, network);
312
Madan Jampani38a88212015-09-15 11:21:27 -0700313 return Collections.unmodifiableCollection(networksMap.values());
314 }
315
316 /**
317 * Returns a collection of tenantNetworks.
318 *
319 * @param nodes the network jsonnodes
320 * @return a collection of tenantNetworks
321 */
322 public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {
323 checkNotNull(nodes, JSON_NOT_NULL);
324 TenantNetwork network = null;
325 ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
326 .newConcurrentMap();
Satish Kab54ffa2015-11-27 14:19:42 +0530327 for (JsonNode node : nodes) {
328 String id = node.get("id").asText();
329 String name = node.get("name").asText();
330 boolean adminStateUp = node.get("admin_state_up").asBoolean();
331 String state = node.get("status").asText();
332 boolean shared = node.get("shared").asBoolean();
lishuai38eeac42016-05-19 15:34:30 +0800333 String tenantIdStr = node.get("tenant_id").asText();
Satish Kab54ffa2015-11-27 14:19:42 +0530334 boolean routerExternal = node.get("router:external")
335 .asBoolean();
336 String type = node.get("provider:network_type").asText();
337 String physicalNetwork = node.get("provider:physical_network").asText();
lishuai38eeac42016-05-19 15:34:30 +0800338 String segmentationIdStr = node.get("provider:segmentation_id").asText();
339 SegmentationId segmentationId = SegmentationId.segmentationId(segmentationIdStr);
340 TenantId tenantId = TenantId.tenantId(tenantIdStr);
Jon Halla3fcf672017-03-28 16:53:22 -0700341 if (segmentationIdStr == null || "null".equals(segmentationIdStr)) {
lishuai38eeac42016-05-19 15:34:30 +0800342 segmentationId = get(VtnRscService.class).getL3vni(tenantId);
343 }
Satish Kab54ffa2015-11-27 14:19:42 +0530344 network = new DefaultTenantNetwork(
345 TenantNetworkId.networkId(id),
346 name,
347 adminStateUp,
348 isState(state),
349 shared,
lishuai38eeac42016-05-19 15:34:30 +0800350 tenantId,
Satish Kab54ffa2015-11-27 14:19:42 +0530351 routerExternal,
352 isType(type),
353 PhysicalNetwork.physicalNetwork(physicalNetwork),
lishuai38eeac42016-05-19 15:34:30 +0800354 segmentationId);
Satish Kab54ffa2015-11-27 14:19:42 +0530355 networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);
Madan Jampani38a88212015-09-15 11:21:27 -0700356 }
Satish Kab54ffa2015-11-27 14:19:42 +0530357
Madan Jampani38a88212015-09-15 11:21:27 -0700358 return Collections.unmodifiableCollection(networksMap.values());
359 }
360
361 /**
362 * Returns the specified item if that items is null; otherwise throws not
363 * found exception.
364 *
365 * @param item item to check
366 * @param <T> item type
367 * @param message not found message
368 * @return item if not null
369 * @throws org.onlab.util.ItemNotFoundException if item is null
370 */
371 protected <T> T nullIsNotFound(T item, String message) {
372 if (item == null) {
373 throw new ItemNotFoundException(message);
374 }
375 return item;
376 }
377}