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