7a0d43d2ee99f2720d6fe70f5c87942215105abf
[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.checkNotNull;\r
19 import static com.google.common.base.Preconditions.checkArgument;\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.Collections;\r
25 import java.util.HashSet;\r
26 import java.util.Iterator;\r
27 import java.util.Set;\r
28 import java.util.concurrent.ConcurrentMap;\r
29 \r
30 import javax.ws.rs.Consumes;\r
31 import javax.ws.rs.DELETE;\r
32 import javax.ws.rs.GET;\r
33 import javax.ws.rs.POST;\r
34 import javax.ws.rs.PUT;\r
35 import javax.ws.rs.Path;\r
36 import javax.ws.rs.PathParam;\r
37 import javax.ws.rs.Produces;\r
38 import javax.ws.rs.QueryParam;\r
39 import javax.ws.rs.core.MediaType;\r
40 import javax.ws.rs.core.Response;\r
41 \r
42 import org.onlab.util.ItemNotFoundException;\r
43 import org.onosproject.rest.AbstractWebResource;\r
44 import org.onosproject.vtnrsc.DefaultTenantNetwork;\r
45 import org.onosproject.vtnrsc.PhysicalNetwork;\r
46 import org.onosproject.vtnrsc.SegmentationId;\r
47 import org.onosproject.vtnrsc.TenantId;\r
48 import org.onosproject.vtnrsc.TenantNetwork;\r
49 import org.onosproject.vtnrsc.TenantNetworkId;\r
50 import org.onosproject.vtnrsc.TenantNetwork.State;\r
51 import org.onosproject.vtnrsc.TenantNetwork.Type;\r
52 import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;\r
53 import org.onosproject.vtnrsc.web.TenantNetworkCodec;\r
54 import org.slf4j.Logger;\r
55 import org.slf4j.LoggerFactory;\r
56 \r
57 import com.fasterxml.jackson.databind.JsonNode;\r
58 import com.fasterxml.jackson.databind.ObjectMapper;\r
59 import com.fasterxml.jackson.databind.node.ObjectNode;\r
60 import com.google.common.collect.Maps;\r
61 \r
62 /**\r
63  * REST resource for interacting with the inventory of networks.\r
64  */\r
65 @Path("networks")\r
66 public class TenantNetworkWebResource extends AbstractWebResource {\r
67     public static final String NETWORK_NOT_FOUND = "Network is not found";\r
68     public static final String NETWORK_ID_EXIST = "Network id is existed";\r
69     public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";\r
70     public static final String CREATE_NETWORK = "create network";\r
71     public static final String UPDATE_NETWORK = "update network";\r
72     public static final String DELETE_NETWORK = "delete network";\r
73     public static final String JSON_NOT_NULL = "JsonNode can not be null";\r
74 \r
75     protected static final Logger log = LoggerFactory\r
76             .getLogger(TenantNetworkWebResource.class);\r
77     private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps\r
78             .newConcurrentMap();\r
79 \r
80     @GET\r
81     @Produces({ MediaType.APPLICATION_JSON })\r
82     public Response getNetworks(@QueryParam("id") String queryId,\r
83                                 @QueryParam("name") String queryName,\r
84                                 @QueryParam("admin_state_up") String queryadminStateUp,\r
85                                 @QueryParam("status") String querystate,\r
86                                 @QueryParam("shared") String queryshared,\r
87                                 @QueryParam("tenant_id") String querytenantId,\r
88                                 @QueryParam("router:external") String routerExternal,\r
89                                 @QueryParam("provider:network_type") String type,\r
90                                 @QueryParam("provider:physical_network") String physicalNetwork,\r
91                                 @QueryParam("provider:segmentation_id") String segmentationId) {\r
92         Iterable<TenantNetwork> networks = get(TenantNetworkService.class)\r
93                 .getNetworks();\r
94         Iterator<TenantNetwork> networkors = networks.iterator();\r
95         while (networkors.hasNext()) {\r
96             TenantNetwork network = networkors.next();\r
97             if ((queryId == null || queryId.equals(network.id().toString()))\r
98                     && (queryName == null || queryName.equals(network.name()\r
99                             .toString()))\r
100                     && (queryadminStateUp == null || queryadminStateUp\r
101                             .equals(network.adminStateUp()))\r
102                     && (querystate == null || querystate.equals(network.state()\r
103                             .toString()))\r
104                     && (queryshared == null || queryshared.equals(network\r
105                             .shared()))\r
106                     && (querytenantId == null || querytenantId.equals(network\r
107                             .tenantId().toString()))\r
108                     && (routerExternal == null || routerExternal.equals(network\r
109                             .routerExternal()))\r
110                     && (type == null || type.equals(network.type()))\r
111                     && (physicalNetwork == null || physicalNetwork\r
112                             .equals(network.physicalNetwork()))\r
113                     && (segmentationId == null || segmentationId.equals(network\r
114                             .segmentationId()))) {\r
115                 networksMap.putIfAbsent(network.id(), network);\r
116             }\r
117         }\r
118         networks = Collections.unmodifiableCollection(networksMap.values());\r
119         ObjectNode result = new ObjectMapper().createObjectNode();\r
120         result.set("networks", new TenantNetworkCodec().encode(networks, this));\r
121 \r
122         return ok(result.toString()).build();\r
123     }\r
124 \r
125     private State isState(String state) {\r
126         if (state.equals("ACTIVE")) {\r
127             return TenantNetwork.State.ACTIVE;\r
128         } else if (state.equals("BUILD")) {\r
129             return TenantNetwork.State.BUILD;\r
130         } else if (state.equals("DOWN")) {\r
131             return TenantNetwork.State.DOWN;\r
132         } else if (state.equals("ERROR")) {\r
133             return TenantNetwork.State.ERROR;\r
134         } else {\r
135             return null;\r
136         }\r
137     }\r
138 \r
139     private Type isType(String type) {\r
140         if (type.equals("LOCAL")) {\r
141             return TenantNetwork.Type.LOCAL;\r
142         } else {\r
143             return null;\r
144         }\r
145     }\r
146 \r
147     @GET\r
148     @Path("{id}")\r
149     @Produces({ MediaType.APPLICATION_JSON })\r
150     public Response getNetwork(@PathParam("id") String id) {\r
151 \r
152         if (!get(TenantNetworkService.class).exists(TenantNetworkId\r
153                                                             .networkId(id))) {\r
154             return ok("The tenantNetwork does not exists").build();\r
155         }\r
156         TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)\r
157                 .getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);\r
158         ObjectNode result = new ObjectMapper().createObjectNode();\r
159         result.set("network", new TenantNetworkCodec().encode(network, this));\r
160 \r
161         return ok(result.toString()).build();\r
162 \r
163     }\r
164 \r
165     @POST\r
166     @Produces(MediaType.APPLICATION_JSON)\r
167     @Consumes(MediaType.APPLICATION_JSON)\r
168     public Response createNetworks(InputStream input) {\r
169         try {\r
170             ObjectMapper mapper = new ObjectMapper();\r
171             JsonNode cfg = mapper.readTree(input);\r
172             JsonNode nodes = null;\r
173             Iterable<TenantNetwork> networks = null;\r
174             if (cfg.get("network") != null) {\r
175                 nodes = cfg.get("network");\r
176                 if (nodes.isArray()) {\r
177                     networks = changeJson2objs(nodes);\r
178                 } else {\r
179                     networks = changeJson2obj(CREATE_NETWORK, null, nodes);\r
180                 }\r
181             } else if (cfg.get("networks") != null) {\r
182                 nodes = cfg.get("networks");\r
183                 networks = changeJson2objs(nodes);\r
184             }\r
185             Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)\r
186                                                        .createNetworks(networks)),\r
187                                                NETWORK_NOT_FOUND);\r
188 \r
189             if (!issuccess) {\r
190                 return Response.status(INTERNAL_SERVER_ERROR)\r
191                         .entity(NETWORK_ID_EXIST).build();\r
192             }\r
193             return Response.status(OK).entity(issuccess.toString()).build();\r
194         } catch (Exception e) {\r
195             log.error("Creates tenantNetwork exception {}.", e.toString());\r
196             return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())\r
197                     .build();\r
198         }\r
199     }\r
200 \r
201     @PUT\r
202     @Path("{id}")\r
203     @Produces(MediaType.APPLICATION_JSON)\r
204     @Consumes(MediaType.APPLICATION_JSON)\r
205     public Response updateNetworks(@PathParam("id") String id, InputStream input) {\r
206         try {\r
207             ObjectMapper mapper = new ObjectMapper();\r
208             JsonNode cfg = mapper.readTree(input);\r
209             JsonNode nodes = null;\r
210             Iterable<TenantNetwork> networks = null;\r
211             if (cfg.get("network") != null) {\r
212                 nodes = cfg.get("network");\r
213                 if (nodes.isArray()) {\r
214                     networks = changeJson2objs(nodes);\r
215                 } else {\r
216                     networks = changeJson2obj(UPDATE_NETWORK,\r
217                                               TenantNetworkId.networkId(id),\r
218                                               nodes);\r
219                 }\r
220             } else if (cfg.get("networks") != null) {\r
221                 nodes = cfg.get("networks");\r
222                 networks = changeJson2objs(nodes);\r
223             }\r
224             Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)\r
225                                                        .updateNetworks(networks)),\r
226                                                NETWORK_NOT_FOUND);\r
227             if (!issuccess) {\r
228                 return Response.status(INTERNAL_SERVER_ERROR)\r
229                         .entity(NETWORK_ID_NOT_EXIST).build();\r
230             }\r
231             return Response.status(OK).entity(issuccess.toString()).build();\r
232         } catch (Exception e) {\r
233             log.error("Updates tenantNetwork failed because of exception {}.",\r
234                       e.toString());\r
235             return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())\r
236                     .build();\r
237         }\r
238     }\r
239 \r
240     @DELETE\r
241     @Path("{id}")\r
242     public Response deleteNetworks(@PathParam("id") String id) {\r
243         log.debug("Deletes network by identifier {}.", id);\r
244         Set<TenantNetworkId> networkSet = new HashSet<TenantNetworkId>();\r
245         networkSet.add(TenantNetworkId.networkId(id));\r
246         Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)\r
247                 .removeNetworks(networkSet), NETWORK_NOT_FOUND);\r
248         if (!issuccess) {\r
249             log.debug("Network identifier {} is not existed", id);\r
250             return Response.status(INTERNAL_SERVER_ERROR)\r
251                     .entity(NETWORK_ID_NOT_EXIST).build();\r
252         }\r
253         return Response.status(OK).entity(issuccess.toString()).build();\r
254     }\r
255 \r
256     /**\r
257      * Returns a collection of tenantNetworks.\r
258      *\r
259      * @param flag the flag\r
260      * @param networkId network identifier\r
261      * @param node the network json node\r
262      * @return a collection of tenantNetworks\r
263      */\r
264     public Iterable<TenantNetwork> changeJson2obj(String flag,\r
265                                                   TenantNetworkId networkId,\r
266                                                   JsonNode node) {\r
267         checkNotNull(node, JSON_NOT_NULL);\r
268         TenantNetwork network = null;\r
269         ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps\r
270                 .newConcurrentMap();\r
271         if (node != null) {\r
272             checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");\r
273             checkArgument(node.get("shared").isBoolean(), "shared should be boolean");\r
274             checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean");\r
275             String name = node.get("name").asText();\r
276             boolean adminStateUp = node.get("admin_state_up").asBoolean();\r
277             String state = node.get("status").asText();\r
278             boolean shared = node.get("shared").asBoolean();\r
279             String tenantId = node.get("tenant_id").asText();\r
280             boolean routerExternal = node.get("router:external").asBoolean();\r
281             String type = node.get("provider:network_type").asText();\r
282             String physicalNetwork = node.get("provider:physical_network")\r
283                     .asText();\r
284             String segmentationId = node.get("provider:segmentation_id")\r
285                     .asText();\r
286             TenantNetworkId id = null;\r
287             if (flag == CREATE_NETWORK) {\r
288                 id = TenantNetworkId.networkId(node.get("id").asText());\r
289             } else if (flag == UPDATE_NETWORK) {\r
290                 id = networkId;\r
291             }\r
292             network = new DefaultTenantNetwork(\r
293                                                id,\r
294                                                name,\r
295                                                adminStateUp,\r
296                                                isState(state),\r
297                                                shared,\r
298                                                TenantId.tenantId(tenantId),\r
299                                                routerExternal,\r
300                                                isType(type),\r
301                                                PhysicalNetwork\r
302                                                        .physicalNetwork(physicalNetwork),\r
303                                                SegmentationId\r
304                                                        .segmentationId(segmentationId));\r
305             networksMap.putIfAbsent(id, network);\r
306         }\r
307         return Collections.unmodifiableCollection(networksMap.values());\r
308     }\r
309 \r
310     /**\r
311      * Returns a collection of tenantNetworks.\r
312      *\r
313      * @param nodes the network jsonnodes\r
314      * @return a collection of tenantNetworks\r
315      */\r
316     public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {\r
317         checkNotNull(nodes, JSON_NOT_NULL);\r
318         TenantNetwork network = null;\r
319         ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps\r
320                 .newConcurrentMap();\r
321         if (nodes != null) {\r
322             for (JsonNode node : nodes) {\r
323                 String id = node.get("id").asText();\r
324                 String name = node.get("name").asText();\r
325                 boolean adminStateUp = node.get("admin_state_up").asBoolean();\r
326                 String state = node.get("status").asText();\r
327                 boolean shared = node.get("shared").asBoolean();\r
328                 String tenantId = node.get("tenant_id").asText();\r
329                 boolean routerExternal = node.get("router:external")\r
330                         .asBoolean();\r
331                 String type = node.get("provider:network_type").asText();\r
332                 String physicalNetwork = node.get("provider:physical_network")\r
333                         .asText();\r
334                 String segmentationId = node.get("provider:segmentation_id")\r
335                         .asText();\r
336                 network = new DefaultTenantNetwork(\r
337                                                    TenantNetworkId\r
338                                                            .networkId(id),\r
339                                                    name,\r
340                                                    adminStateUp,\r
341                                                    isState(state),\r
342                                                    shared,\r
343                                                    TenantId.tenantId(tenantId),\r
344                                                    routerExternal,\r
345                                                    isType(type),\r
346                                                    PhysicalNetwork\r
347                                                            .physicalNetwork(physicalNetwork),\r
348                                                    SegmentationId\r
349                                                            .segmentationId(segmentationId));\r
350                 networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);\r
351             }\r
352         }\r
353         return Collections.unmodifiableCollection(networksMap.values());\r
354     }\r
355 \r
356     /**\r
357      * Returns the specified item if that items is null; otherwise throws not\r
358      * found exception.\r
359      *\r
360      * @param item item to check\r
361      * @param <T> item type\r
362      * @param message not found message\r
363      * @return item if not null\r
364      * @throws org.onlab.util.ItemNotFoundException if item is null\r
365      */\r
366     protected <T> T nullIsNotFound(T item, String message) {\r
367         if (item == null) {\r
368             throw new ItemNotFoundException(message);\r
369         }\r
370         return item;\r
371     }\r
372 }\r