addee418130dbf66e48fd945f151ada7e780d8ef
[vtn.git] /
1 /*
2  * Copyright (c) 2014-2015 NEC Corporation
3  * All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this
7  * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.vtn.manager.northbound;
11
12 import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
13 import static java.net.HttpURLConnection.HTTP_CREATED;
14 import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
15 import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
16 import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
17 import static java.net.HttpURLConnection.HTTP_OK;
18 import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
19 import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
20 import static java.net.HttpURLConnection.HTTP_UNSUPPORTED_TYPE;
21
22 import javax.ws.rs.Consumes;
23 import javax.ws.rs.DELETE;
24 import javax.ws.rs.GET;
25 import javax.ws.rs.PUT;
26 import javax.ws.rs.Path;
27 import javax.ws.rs.PathParam;
28 import javax.ws.rs.Produces;
29 import javax.ws.rs.core.Context;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
32 import javax.ws.rs.core.UriInfo;
33
34 import org.codehaus.enunciate.jaxrs.ResponseCode;
35 import org.codehaus.enunciate.jaxrs.ResponseHeader;
36 import org.codehaus.enunciate.jaxrs.ResponseHeaders;
37 import org.codehaus.enunciate.jaxrs.StatusCodes;
38 import org.codehaus.enunciate.jaxrs.TypeHint;
39
40 import org.opendaylight.vtn.manager.IVTNManager;
41 import org.opendaylight.vtn.manager.PathMap;
42 import org.opendaylight.vtn.manager.VTNException;
43 import org.opendaylight.vtn.manager.VTenantPath;
44
45 import org.opendaylight.controller.sal.authorization.Privilege;
46 import org.opendaylight.controller.sal.core.UpdateType;
47 import org.opendaylight.controller.sal.utils.Status;
48
49 /**
50  * This class provides Northbound REST APIs to handle VTN path map.
51  *
52  * <p>
53  *   Path maps configured in the VTN path map list affect flows in that VTN.
54  *   If an incoming packet matches the flow condition configured in VTN path
55  *   map, the route of that packet is determined by the path policy configured
56  *   in that path map. If no VTN path map matches an incoming packet,
57  *   container path maps are evaluated.
58  * </p>
59  *
60  * @since Helium
61  */
62 @Path("/default/vtns/{tenantName}/pathmaps")
63 public class VTenantPathMapNorthbound extends VTNNorthBoundBase {
64     /**
65      * Return information about VTN pathmap configured in the specified VTN.
66      *
67      * @param tenantName  The name of the VTN.
68      * @return  <strong>pathmaps</strong> element contains information
69      *          about VTN path map list specified by the requested URI.
70      */
71     @GET
72     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
73     @TypeHint(PathMapList.class)
74     @StatusCodes({
75         @ResponseCode(code = HTTP_OK,
76                       condition = "Operation completed successfully."),
77         @ResponseCode(code = HTTP_UNAUTHORIZED,
78                       condition = "User is not authorized to perform this " +
79                       "operation."),
80         @ResponseCode(code = HTTP_NOT_FOUND,
81                       condition = "The specified VTN does not exist."),
82         @ResponseCode(code = HTTP_INTERNAL_ERROR,
83                       condition = "Fatal internal error occurred in the " +
84                       "VTN Manager."),
85         @ResponseCode(code = HTTP_UNAVAILABLE,
86                       condition = "One or more of mandatory controller " +
87                       "services, such as the VTN Manager, are unavailable.")})
88     public PathMapList getPathMaps(
89             @PathParam("tenantName") String tenantName) {
90         checkPrivilege(Privilege.READ);
91
92         IVTNManager mgr = getVTNManager();
93         VTenantPath path = new VTenantPath(tenantName);
94         try {
95             return new PathMapList(mgr.getPathMaps(path));
96         } catch (VTNException e) {
97             throw getException(e);
98         }
99     }
100
101     /**
102      * Delete all the VTN path maps configured in the specified VTN.
103      *
104      * @param tenantName  The name of the VTN.
105      * @return Response as dictated by the HTTP Response Status code.
106      * @since  Lithium
107      */
108     @DELETE
109     @TypeHint(TypeHint.NO_CONTENT.class)
110     @StatusCodes({
111         @ResponseCode(code = HTTP_OK,
112                       condition = "At least one VTN path map was deleted " +
113                       "successfully."),
114         @ResponseCode(code = HTTP_NO_CONTENT,
115                       condition = "No VTN path map is present."),
116         @ResponseCode(code = HTTP_UNAUTHORIZED,
117                       condition = "User is not authorized to perform this " +
118                       "operation."),
119         @ResponseCode(code = HTTP_NOT_FOUND,
120                       condition = "The specified VTN does not exist."),
121         @ResponseCode(code = HTTP_INTERNAL_ERROR,
122                       condition = "Fatal internal error occurred in the " +
123                       "VTN Manager."),
124         @ResponseCode(code = HTTP_UNAVAILABLE,
125                       condition = "One or more of mandatory controller " +
126                       "services, such as the VTN Manager, are unavailable.")})
127     public Response clearPathMap(@PathParam("tenantName") String tenantName) {
128         checkPrivilege(Privilege.WRITE);
129
130         IVTNManager mgr = getVTNManager();
131         VTenantPath path = new VTenantPath(tenantName);
132         Status status = mgr.clearPathMap(path);
133         if (status == null) {
134             return Response.noContent().build();
135         }
136         if (status.isSuccess()) {
137             return Response.ok().build();
138         }
139
140         throw getException(status);
141     }
142
143     /**
144      * Return information about the VTN path map specified by the path map
145      * index inside the specified VTN.
146      *
147      * @param tenantName  The name of the VTN.
148      * @param index
149      *   The index value which specifies the path map in the VTN path map list.
150      *   A string representation of an integer value must be specified.
151      * @return  <strong>pathmap</strong> element contains information
152      *          about the path map specified by the requested URI.
153      */
154     @Path("{index}")
155     @GET
156     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
157     @TypeHint(PathMap.class)
158     @StatusCodes({
159         @ResponseCode(code = HTTP_OK,
160                       condition = "Operation completed successfully."),
161         @ResponseCode(code = HTTP_NO_CONTENT,
162                       condition = "The specified path map does not exist " +
163                       "in the default container."),
164         @ResponseCode(code = HTTP_UNAUTHORIZED,
165                       condition = "User is not authorized to perform this " +
166                       "operation."),
167         @ResponseCode(code = HTTP_NOT_FOUND,
168                       condition = "<ul>" +
169                       "<li>The specified VTN does not exist.</li>" +
170                       "<li>A string passed to <u>{index}</u> can not be " +
171                       "converted into an integer.</li>" +
172                       "</ul>"),
173         @ResponseCode(code = HTTP_INTERNAL_ERROR,
174                       condition = "Fatal internal error occurred in the " +
175                       "VTN Manager."),
176         @ResponseCode(code = HTTP_UNAVAILABLE,
177                       condition = "One or more of mandatory controller " +
178                       "services, such as the VTN Manager, are unavailable.")})
179     public PathMap getPathMap(
180             @PathParam("tenantName") String tenantName,
181             @PathParam("index") int index) {
182         checkPrivilege(Privilege.READ);
183
184         IVTNManager mgr = getVTNManager();
185         VTenantPath path = new VTenantPath(tenantName);
186         try {
187             return mgr.getPathMap(path, index);
188         } catch (VTNException e) {
189             throw getException(e);
190         }
191     }
192
193     /**
194      * Create or modify the VTN path map specified by the index number
195      * inside the specified VTN.
196      *
197      * <ul>
198      *   <li>
199      *     If the container path map specified by
200      *     <span style="text-decoration: underline;">{index}</span> does not
201      *     exist, a new VTN path map will be associated with
202      *     <span style="text-decoration: underline;">{index}</span> in the
203      *     VTN path map list.
204      *   </li>
205      *   <li>
206      *     If the VTN path map specified by
207      *     <span style="text-decoration: underline;">{index}</span> already
208      *     exists, it will be modified as specified by <strong>pathmap</strong>
209      *     element.
210      *   </li>
211      * </ul>
212      *
213      * @param uriInfo     Requested URI information.
214      * @param tenantName  The name of the VTN.
215      * @param index
216      *   The index value which specifies the path map in the VTN path map list.
217      *   <ul>
218      *     <li>
219      *       A string representation of an integer value must be specified.
220      *     </li>
221      *     <li>
222      *       The range of value that can be specified is from
223      *       <strong>1</strong> to <strong>65535</strong>.
224      *     </li>
225      *   </ul>
226      * @param pmap
227      *   <strong>pathmap</strong> element specifies the configuration of the
228      *   path map.
229      *   <ul>
230      *     <li>
231      *       <strong>index</strong> attribute in the <strong>pathmap</strong>
232      *       element is always ignored. The index number is determined by the
233      *       <span style="text-decoration: underline;">{index}</span>
234      *       parameter.
235      *     </li>
236      *     <li>
237      *       Note that this API does not check whether the flow condition
238      *       specified by <strong>condition</strong> attribute in
239      *       <strong>pathmap</strong> element actually exists or not.
240      *       The path map will be invalidated if the specified flow condition
241      *       does not exist.
242      *     </li>
243      *     <li>
244      *       Note that this API does not check whether the path policy
245      *       specified by <strong>policy</strong> attribute in
246      *       <strong>pathmap</strong> element actually exists or not.
247      *       The path map will be invalidated if the specified path policy
248      *       does not exist.
249      *     </li>
250      *   </ul>
251      * @return Response as dictated by the HTTP Response Status code.
252      */
253     @Path("{index}")
254     @PUT
255     @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
256     @TypeHint(TypeHint.NO_CONTENT.class)
257     @ResponseHeaders({
258         @ResponseHeader(name = "Location",
259                         description = "URI corresponding to the newly " +
260                         "created path map, which is the same URI specified " +
261                         "in request. This header is set only if " +
262                         "CREATED(201) is returned as response code.")})
263     @StatusCodes({
264         @ResponseCode(code = HTTP_OK,
265                       condition = "Existing path map was modified " +
266                       "successfully."),
267         @ResponseCode(code = HTTP_CREATED,
268                       condition = "Path map was newly created " +
269                       "successfully."),
270         @ResponseCode(code = HTTP_NO_CONTENT,
271                       condition = "Path map was not changed."),
272         @ResponseCode(code = HTTP_BAD_REQUEST,
273                       condition = "<ul>" +
274                       "<li>Incorrect XML or JSON data is specified " +
275                       "in Request body.</li>" +
276                       "<li>Index number specified by <u>{index}</u> " +
277                       "parameter is out of valid range.</li>" +
278                       "<li>Incorrect value is configured in " +
279                       "<strong>pathmap</strong>.</li>" +
280                       "</ul>"),
281         @ResponseCode(code = HTTP_UNAUTHORIZED,
282                       condition = "User is not authorized to perform this " +
283                       "operation."),
284         @ResponseCode(code = HTTP_NOT_FOUND,
285                       condition = "<ul>" +
286                       "<li>The specified VTN does not exist.</li>" +
287                       "<li>A string passed to <u>{index}</u> can not be " +
288                       "converted into an integer.</li>" +
289                       "</ul>"),
290         @ResponseCode(code = HTTP_UNSUPPORTED_TYPE,
291                       condition = "Unsupported data type is specified in " +
292                       "<strong>Content-Type</strong> header."),
293         @ResponseCode(code = HTTP_INTERNAL_ERROR,
294                       condition = "Fatal internal error occurred in the " +
295                       "VTN Manager."),
296         @ResponseCode(code = HTTP_UNAVAILABLE,
297                       condition = "One or more of mandatory controller " +
298                       "services, such as the VTN Manager, are unavailable.")})
299     public Response putPathMap(
300             @Context UriInfo uriInfo,
301             @PathParam("tenantName") String tenantName,
302             @PathParam("index") int index,
303             @TypeHint(PathMap.class) PathMap pmap) {
304         checkPrivilege(Privilege.WRITE);
305
306         IVTNManager mgr = getVTNManager();
307         VTenantPath path = new VTenantPath(tenantName);
308         try {
309             UpdateType result = mgr.setPathMap(path, index, pmap);
310             if (result == null) {
311                 return Response.noContent().build();
312             }
313             if (result == UpdateType.ADDED) {
314                 // Return CREATED with Location header.
315                 return Response.created(uriInfo.getAbsolutePath()).build();
316             }
317
318             return Response.ok().build();
319         } catch (VTNException e) {
320             throw getException(e);
321         }
322     }
323
324     /**
325      * Delete the VTN path map specified by the index number inside the
326      * specified VTN.
327      *
328      * @param tenantName  The name of the VTN.
329      * @param index
330      *   The index value which specifies the path map in the VTN path map list.
331      *   A string representation of an integer value must be specified.
332      * @return Response as dictated by the HTTP Response Status code.
333      */
334     @Path("{index}")
335     @DELETE
336     @TypeHint(TypeHint.NO_CONTENT.class)
337     @StatusCodes({
338         @ResponseCode(code = HTTP_OK,
339                       condition = "Path map was deleted successfully."),
340         @ResponseCode(code = HTTP_NO_CONTENT,
341                       condition = "The specified path map does not exist " +
342                       "in the specified VTN."),
343         @ResponseCode(code = HTTP_UNAUTHORIZED,
344                       condition = "User is not authorized to perform this " +
345                       "operation."),
346         @ResponseCode(code = HTTP_NOT_FOUND,
347                       condition = "<ul>" +
348                       "<li>The specified VTN does not exist.</li>" +
349                       "<li>A string passed to <u>{index}</u> can not be " +
350                       "converted into an integer.</li>" +
351                       "</ul>"),
352         @ResponseCode(code = HTTP_INTERNAL_ERROR,
353                       condition = "Fatal internal error occurred in the " +
354                       "VTN Manager."),
355         @ResponseCode(code = HTTP_UNAVAILABLE,
356                       condition = "One or more of mandatory controller " +
357                       "services, such as the VTN Manager, are unavailable.")})
358     public Response deletePathMap(
359             @PathParam("tenantName") String tenantName,
360             @PathParam("index") int index) {
361         checkPrivilege(Privilege.WRITE);
362
363         IVTNManager mgr = getVTNManager();
364         VTenantPath path = new VTenantPath(tenantName);
365         Status status = mgr.removePathMap(path, index);
366         if (status == null) {
367             return Response.noContent().build();
368         }
369         if (status.isSuccess()) {
370             return Response.ok().build();
371         }
372
373         throw getException(status);
374     }
375 }