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