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