blob: 014b5637c790ed63a7e3be0470c2d9389de4744f [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 com.google.common.collect.Sets;
Madan Jampani38a88212015-09-15 11:21:27 -070023import org.onlab.packet.IpAddress;
24import org.onlab.packet.MacAddress;
25import org.onlab.util.ItemNotFoundException;
26import org.onosproject.net.DeviceId;
27import org.onosproject.rest.AbstractWebResource;
28import org.onosproject.vtnrsc.AllowedAddressPair;
29import org.onosproject.vtnrsc.BindingHostId;
30import org.onosproject.vtnrsc.DefaultVirtualPort;
31import org.onosproject.vtnrsc.FixedIp;
32import org.onosproject.vtnrsc.SecurityGroup;
33import org.onosproject.vtnrsc.SubnetId;
34import org.onosproject.vtnrsc.TenantId;
35import org.onosproject.vtnrsc.TenantNetworkId;
36import org.onosproject.vtnrsc.VirtualPort;
37import org.onosproject.vtnrsc.VirtualPort.State;
38import org.onosproject.vtnrsc.VirtualPortId;
39import org.onosproject.vtnrsc.virtualport.VirtualPortService;
onosjcc36e04a82015-10-27 16:46:37 +080040import org.onosproject.vtnweb.web.VirtualPortCodec;
Madan Jampani38a88212015-09-15 11:21:27 -070041import org.slf4j.Logger;
42import org.slf4j.LoggerFactory;
43
Jian Lic2a542b2016-05-10 11:48:19 -070044import javax.ws.rs.Consumes;
45import javax.ws.rs.DELETE;
46import javax.ws.rs.GET;
47import javax.ws.rs.POST;
48import javax.ws.rs.PUT;
49import javax.ws.rs.Path;
50import javax.ws.rs.PathParam;
51import javax.ws.rs.Produces;
52import javax.ws.rs.core.MediaType;
53import javax.ws.rs.core.Response;
54import java.io.InputStream;
55import java.util.Collection;
56import java.util.Collections;
57import java.util.HashMap;
58import java.util.HashSet;
59import java.util.Map;
60import java.util.Set;
61import java.util.concurrent.ConcurrentMap;
62
63import static com.google.common.base.Preconditions.checkArgument;
64import static com.google.common.base.Preconditions.checkNotNull;
65import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
66import static javax.ws.rs.core.Response.Status.NOT_FOUND;
67import static javax.ws.rs.core.Response.Status.OK;
Ray Milkey86ee5e82018-04-02 15:33:07 -070068import static org.onlab.util.Tools.readTreeFromStream;
Madan Jampani38a88212015-09-15 11:21:27 -070069
70/**
71 * REST resource for interacting with the inventory of infrastructure
72 * virtualPort.
73 */
74@Path("ports")
75public class VirtualPortWebResource extends AbstractWebResource {
76 public static final String VPORT_NOT_FOUND = "VirtualPort is not found";
77 public static final String VPORT_ID_EXIST = "VirtualPort id is exist";
78 public static final String VPORT_ID_NOT_EXIST = "VirtualPort id is not exist";
79 public static final String JSON_NOT_NULL = "JsonNode can not be null";
Ray Milkey9c9cde42018-01-12 14:22:06 -080080 private static final Logger log = LoggerFactory
Madan Jampani38a88212015-09-15 11:21:27 -070081 .getLogger(VirtualPortService.class);
82
83 @GET
Wu wenbind0b119f2016-05-11 18:03:41 +080084 @Produces(MediaType.APPLICATION_JSON)
85 @Consumes(MediaType.APPLICATION_JSON)
Madan Jampani38a88212015-09-15 11:21:27 -070086 public Response getPorts() {
87 Iterable<VirtualPort> virtualPorts = get(VirtualPortService.class)
88 .getPorts();
89 ObjectNode result = new ObjectMapper().createObjectNode();
90 result.set("ports", new VirtualPortCodec().encode(virtualPorts, this));
91 return ok(result.toString()).build();
92 }
93
94 @GET
95 @Path("{id}")
Wu wenbind0b119f2016-05-11 18:03:41 +080096 @Produces(MediaType.APPLICATION_JSON)
97 @Consumes(MediaType.APPLICATION_JSON)
Madan Jampani38a88212015-09-15 11:21:27 -070098 public Response getportsById(@PathParam("id") String id) {
99
100 if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
lishuai0f47f342015-09-16 11:38:48 +0800101 return Response.status(NOT_FOUND)
102 .entity(VPORT_NOT_FOUND).build();
Madan Jampani38a88212015-09-15 11:21:27 -0700103 }
104 VirtualPort virtualPort = nullIsNotFound(get(VirtualPortService.class)
105 .getPort(VirtualPortId.portId(id)), VPORT_NOT_FOUND);
106 ObjectNode result = new ObjectMapper().createObjectNode();
107 result.set("port", new VirtualPortCodec().encode(virtualPort, this));
108 return ok(result.toString()).build();
109 }
110
111 @POST
112 @Consumes(MediaType.APPLICATION_JSON)
113 @Produces(MediaType.APPLICATION_JSON)
114 public Response createPorts(InputStream input) {
115 try {
116 ObjectMapper mapper = new ObjectMapper();
Ray Milkey86ee5e82018-04-02 15:33:07 -0700117 JsonNode cfg = readTreeFromStream(mapper, input);
Madan Jampani38a88212015-09-15 11:21:27 -0700118 Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
119 Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
120 .createPorts(vPorts), VPORT_NOT_FOUND);
121 if (!issuccess) {
122 return Response.status(INTERNAL_SERVER_ERROR)
123 .entity(VPORT_ID_NOT_EXIST).build();
124 }
125 return Response.status(OK).entity(issuccess.toString()).build();
126 } catch (Exception e) {
127 log.error("Creates VirtualPort failed because of exception {}",
128 e.toString());
129 return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
130 .build();
131 }
132 }
133
Madan Jampani38a88212015-09-15 11:21:27 -0700134 @DELETE
Wu wenbinb0bd6132016-05-10 19:20:23 +0800135 @Path("{portUUID}")
136 @Consumes(MediaType.APPLICATION_JSON)
137 @Produces(MediaType.APPLICATION_JSON)
Madan Jampani38a88212015-09-15 11:21:27 -0700138 public Response deletePorts(@PathParam("portUUID") String id) {
139 Set<VirtualPortId> vPortIds = new HashSet<>();
140 try {
141 if (id != null) {
142 vPortIds.add(VirtualPortId.portId(id));
143 }
144 Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
145 .removePorts(vPortIds), VPORT_NOT_FOUND);
146 if (!issuccess) {
147 return Response.status(INTERNAL_SERVER_ERROR)
148 .entity(VPORT_ID_NOT_EXIST).build();
149 }
Jian Lic2a542b2016-05-10 11:48:19 -0700150 return ok(issuccess.toString()).build();
Madan Jampani38a88212015-09-15 11:21:27 -0700151 } catch (Exception e) {
152 log.error("Deletes VirtualPort failed because of exception {}",
153 e.toString());
154 return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
155 .build();
156 }
157 }
158
159 @PUT
160 @Path("{id}")
161 @Consumes(MediaType.APPLICATION_JSON)
162 @Produces(MediaType.APPLICATION_JSON)
163 public Response updatePorts(@PathParam("id") String id, InputStream input) {
164 try {
165 ObjectMapper mapper = new ObjectMapper();
Ray Milkey86ee5e82018-04-02 15:33:07 -0700166 JsonNode cfg = readTreeFromStream(mapper, input);
Madan Jampani38a88212015-09-15 11:21:27 -0700167 Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
168 Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
169 .updatePorts(vPorts), VPORT_NOT_FOUND);
170 if (!issuccess) {
171 return Response.status(INTERNAL_SERVER_ERROR)
172 .entity(VPORT_ID_NOT_EXIST).build();
173 }
174 return Response.status(OK).entity(issuccess.toString()).build();
175 } catch (Exception e) {
176 log.error("Updates failed because of exception {}", e.toString());
177 return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
178 .build();
179 }
180 }
181
182 /**
183 * Returns a Object of the currently known infrastructure virtualPort.
184 *
185 * @param vPortNode the virtualPort json node
186 * @return a collection of virtualPorts
187 */
188 public Iterable<VirtualPort> createOrUpdateByInputStream(JsonNode vPortNode) {
189 checkNotNull(vPortNode, JSON_NOT_NULL);
190 JsonNode vPortNodes = vPortNode.get("ports");
191 if (vPortNodes == null) {
192 vPortNodes = vPortNode.get("port");
193 }
194 if (vPortNodes.isArray()) {
195 return changeJsonToPorts(vPortNodes);
196 } else {
197 return changeJsonToPort(vPortNodes);
198 }
199 }
200
201 /**
202 * Returns the iterable collection of virtualports from subnetNodes.
203 *
204 * @param vPortNodes the virtualPort json node
205 * @return virtualPorts a collection of virtualPorts
206 */
207 public Iterable<VirtualPort> changeJsonToPorts(JsonNode vPortNodes) {
208 checkNotNull(vPortNodes, JSON_NOT_NULL);
209 Map<VirtualPortId, VirtualPort> portMap = new HashMap<>();
210 Map<String, String> strMap = new HashMap<>();
211 for (JsonNode vPortnode : vPortNodes) {
212 VirtualPortId id = VirtualPortId.portId(vPortnode.get("id")
213 .asText());
214 String name = vPortnode.get("name").asText();
215 TenantId tenantId = TenantId.tenantId(vPortnode.get("tenant_id")
216 .asText());
217 TenantNetworkId networkId = TenantNetworkId.networkId(vPortnode
218 .get("network_id").asText());
219 checkArgument(vPortnode.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
220 Boolean adminStateUp = vPortnode.get("admin_state_up").asBoolean();
221 String state = vPortnode.get("status").asText();
222 MacAddress macAddress = MacAddress.valueOf(vPortnode
223 .get("mac_address").asText());
224 DeviceId deviceId = DeviceId.deviceId(vPortnode.get("device_id")
225 .asText());
226 String deviceOwner = vPortnode.get("device_owner").asText();
227 JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
228 Set<FixedIp> fixedIps = new HashSet<>();
229 for (JsonNode fixedIpNode : fixedIpNodes) {
230 FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
231 fixedIps.add(fixedIp);
232 }
233
234 BindingHostId bindingHostId = BindingHostId
235 .bindingHostId(vPortnode.get("binding:host_id").asText());
236 String bindingVnicType = vPortnode.get("binding:vnic_type")
237 .asText();
238 String bindingVifType = vPortnode.get("binding:vif_type").asText();
239 String bindingVifDetails = vPortnode.get("binding:vif_details")
240 .asText();
241 JsonNode allowedAddressPairJsonNode = vPortnode
242 .get("allowed_address_pairs");
243 Collection<AllowedAddressPair> allowedAddressPairs =
244 jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
245 JsonNode securityGroupNode = vPortnode.get("security_groups");
246 Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
247 strMap.put("name", name);
248 strMap.put("deviceOwner", deviceOwner);
249 strMap.put("bindingVnicType", bindingVnicType);
250 strMap.put("bindingVifType", bindingVifType);
251 strMap.put("bindingVifDetails", bindingVifDetails);
252 VirtualPort vPort = new DefaultVirtualPort(id, networkId,
253 adminStateUp, strMap,
254 isState(state),
255 macAddress, tenantId,
256 deviceId, fixedIps,
257 bindingHostId,
258 Sets.newHashSet(allowedAddressPairs),
259 Sets.newHashSet(securityGroups));
260 portMap.put(id, vPort);
261 }
262 return Collections.unmodifiableCollection(portMap.values());
263 }
264
265 /**
266 * Returns a collection of virtualPorts from subnetNodes.
267 *
268 * @param vPortNodes the virtualPort json node
269 * @return virtualPorts a collection of virtualPorts
270 */
271 public Iterable<VirtualPort> changeJsonToPort(JsonNode vPortNodes) {
272 checkNotNull(vPortNodes, JSON_NOT_NULL);
273 Map<VirtualPortId, VirtualPort> vportMap = new HashMap<>();
274 Map<String, String> strMap = new HashMap<>();
275 VirtualPortId id = VirtualPortId.portId(vPortNodes.get("id").asText());
276 String name = vPortNodes.get("name").asText();
277 TenantId tenantId = TenantId.tenantId(vPortNodes.get("tenant_id")
278 .asText());
279 TenantNetworkId networkId = TenantNetworkId.networkId(vPortNodes
280 .get("network_id").asText());
281 Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
282 String state = vPortNodes.get("status").asText();
283 MacAddress macAddress = MacAddress.valueOf(vPortNodes
284 .get("mac_address").asText());
285 DeviceId deviceId = DeviceId.deviceId(vPortNodes.get("device_id")
286 .asText());
287 String deviceOwner = vPortNodes.get("device_owner").asText();
288 JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
289 Set<FixedIp> fixedIps = new HashSet<>();
290 for (JsonNode fixedIpNode : fixedIpNodes) {
291 FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
292 fixedIps.add(fixedIp);
293 }
294
295 BindingHostId bindingHostId = BindingHostId
296 .bindingHostId(vPortNodes.get("binding:host_id").asText());
297 String bindingVnicType = vPortNodes.get("binding:vnic_type").asText();
298 String bindingVifType = vPortNodes.get("binding:vif_type").asText();
299 String bindingVifDetails = vPortNodes.get("binding:vif_details")
300 .asText();
301 JsonNode allowedAddressPairJsonNode = vPortNodes
302 .get("allowed_address_pairs");
303 Collection<AllowedAddressPair> allowedAddressPairs =
304 jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
305 JsonNode securityGroupNode = vPortNodes.get("security_groups");
306 Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
307 strMap.put("name", name);
308 strMap.put("deviceOwner", deviceOwner);
309 strMap.put("bindingVnicType", bindingVnicType);
310 strMap.put("bindingVifType", bindingVifType);
311 strMap.put("bindingVifDetails", bindingVifDetails);
312 VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
313 strMap, isState(state),
314 macAddress, tenantId,
315 deviceId, fixedIps,
316 bindingHostId,
317 Sets.newHashSet(allowedAddressPairs),
318 Sets.newHashSet(securityGroups));
319 vportMap.put(id, vPort);
320
321 return Collections.unmodifiableCollection(vportMap.values());
322 }
323
324 /**
325 * Returns a Object of the currently known infrastructure virtualPort.
326 *
327 * @param allowedAddressPairs the allowedAddressPairs json node
328 * @return a collection of allowedAddressPair
329 */
330 public Collection<AllowedAddressPair> jsonNodeToAllowedAddressPair(JsonNode allowedAddressPairs) {
331 checkNotNull(allowedAddressPairs, JSON_NOT_NULL);
332 ConcurrentMap<Integer, AllowedAddressPair> allowMaps = Maps
333 .newConcurrentMap();
334 int i = 0;
335 for (JsonNode node : allowedAddressPairs) {
336 IpAddress ip = IpAddress.valueOf(node.get("ip_address").asText());
337 MacAddress mac = MacAddress.valueOf(node.get("mac_address")
338 .asText());
339 AllowedAddressPair allows = AllowedAddressPair
340 .allowedAddressPair(ip, mac);
341 allowMaps.put(i, allows);
342 i++;
343 }
344 log.debug("The jsonNode of allowedAddressPairallow is {}"
345 + allowedAddressPairs.toString());
346 return Collections.unmodifiableCollection(allowMaps.values());
347 }
348
349 /**
350 * Returns a collection of virtualPorts.
351 *
352 * @param securityGroups the virtualPort jsonnode
353 * @return a collection of securityGroups
354 */
355 public Collection<SecurityGroup> jsonNodeToSecurityGroup(JsonNode securityGroups) {
356 checkNotNull(securityGroups, JSON_NOT_NULL);
357 ConcurrentMap<Integer, SecurityGroup> securMaps = Maps
358 .newConcurrentMap();
359 int i = 0;
360 for (JsonNode node : securityGroups) {
361 SecurityGroup securityGroup = SecurityGroup
362 .securityGroup(node.asText());
363 securMaps.put(i, securityGroup);
364 i++;
365 }
366 return Collections.unmodifiableCollection(securMaps.values());
367 }
368
369 /**
370 * Returns a collection of fixedIps.
371 *
372 * @param fixedIpNode the fixedIp jsonnode
373 * @return a collection of SecurityGroup
374 */
375 public FixedIp jsonNodeToFixedIps(JsonNode fixedIpNode) {
376 SubnetId subnetId = SubnetId.subnetId(fixedIpNode.get("subnet_id")
377 .asText());
378 IpAddress ipAddress = IpAddress.valueOf(fixedIpNode.get("ip_address")
379 .asText());
380 FixedIp fixedIps = FixedIp.fixedIp(subnetId, ipAddress);
381 return fixedIps;
382 }
383
384 /**
385 * Returns VirtualPort State.
386 *
387 * @param state the virtualport state
388 * @return the virtualPort state
389 */
390 private State isState(String state) {
Jon Halla3fcf672017-03-28 16:53:22 -0700391 if ("ACTIVE".equals(state)) {
Madan Jampani38a88212015-09-15 11:21:27 -0700392 return VirtualPort.State.ACTIVE;
393 } else {
394 return VirtualPort.State.DOWN;
395 }
396
397 }
398
399 /**
400 * Returns the specified item if that items is null; otherwise throws not
401 * found exception.
402 *
403 * @param item item to check
404 * @param <T> item type
405 * @param message not found message
406 * @return item if not null
407 * @throws org.onlab.util.ItemNotFoundException if item is null
408 */
409 protected <T> T nullIsNotFound(T item, String message) {
410 if (item == null) {
411 throw new ItemNotFoundException(message);
412 }
413 return item;
414 }
415}