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