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