Added more ignorable files to .gitignore
[ovsdb.git] / northbound / src / main / java / org / opendaylight / ovsdb / northbound / OVSDBNorthbound.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc. and others
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
9  */
10 package org.opendaylight.ovsdb.northbound;
11
12 import java.util.List;
13 import java.util.Map;
14
15 import javax.ws.rs.Consumes;
16 import javax.ws.rs.DELETE;
17 import javax.ws.rs.GET;
18 import javax.ws.rs.POST;
19 import javax.ws.rs.PUT;
20 import javax.ws.rs.Path;
21 import javax.ws.rs.PathParam;
22 import javax.ws.rs.core.Context;
23 import javax.ws.rs.core.MediaType;
24 import javax.ws.rs.core.Response;
25 import javax.ws.rs.core.SecurityContext;
26 import javax.ws.rs.core.UriInfo;
27
28 import org.codehaus.enunciate.jaxrs.ResponseCode;
29 import org.codehaus.enunciate.jaxrs.StatusCodes;
30 import org.codehaus.enunciate.jaxrs.TypeHint;
31 import org.opendaylight.controller.northbound.commons.RestMessages;
32 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
33 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
34 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
35 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
36 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
37 import org.opendaylight.controller.sal.authorization.Privilege;
38 import org.opendaylight.controller.sal.core.Node;
39 import org.opendaylight.controller.sal.utils.ServiceHelper;
40 import org.opendaylight.controller.sal.utils.Status;
41 import org.opendaylight.controller.sal.utils.StatusCode;
42 import org.opendaylight.ovsdb.lib.notation.UUID;
43 import org.opendaylight.ovsdb.lib.table.Table;
44 import org.opendaylight.ovsdb.lib.table.Tables;
45 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
46 import org.opendaylight.ovsdb.plugin.StatusWithUuid;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 /**
51 * OVSDB Northbound REST API.<br>
52 * This class provides REST APIs to Create, Read, Update and Delete OVSDB Row in any of the ovsdb table
53 * database one at a time. The JSON used to create rows is in the same format as the OVSDB JSON-RPC messages.
54 * This format is documented in the <a href="http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf">OVSDB Schema</a>
55 * and in <a href="http://tools.ietf.org/rfc/rfc7047.txt">RFC 7047</a>.
56 *
57 * <br>
58 * <br>
59 * Authentication scheme : <b>HTTP Basic</b><br>
60 * Authentication realm : <b>opendaylight</b><br>
61 * Transport : <b>HTTP and HTTPS</b><br>
62 * <br>
63 * HTTPS Authentication is disabled by default.
64 */
65
66 @Path("/")
67 public class OVSDBNorthbound {
68     protected static final Logger logger = LoggerFactory.getLogger(OVSDBNorthbound.class);
69
70     @Context
71     private UriInfo _uriInfo;
72     private String username;
73
74     @Context
75     public void setSecurityContext(SecurityContext context) {
76         if (context != null && context.getUserPrincipal() != null) {
77             username = context.getUserPrincipal().getName();
78         }
79     }
80
81     protected String getUserName() {
82         return username;
83     }
84
85     private void handleNameMismatch(String name, String nameinURL) {
86         if (name == null || nameinURL == null) {
87             throw new BadRequestException(RestMessages.INVALIDDATA.toString() + " : Name is null");
88         }
89
90         if (name.equalsIgnoreCase(nameinURL)) {
91             return;
92         }
93         throw new ResourceConflictException(RestMessages.INVALIDDATA.toString()
94                 + " : Table Name in URL does not match the row name in request body");
95     }
96
97     private String getOVSTableName(String tableName) {
98         List<Table> tables = Tables.getTables();
99         for (Table table : tables) {
100             if (table.getTableName().getName().equalsIgnoreCase(tableName)) {
101                 return table.getTableName().getName();
102             }
103         }
104         // TODO Auto-generated method stub
105         return null;
106     }
107
108     /**
109      * Create a Row
110      *
111      * @param nodeType type of node e.g OVS
112      * @param nodeId ID of the node
113      * @param tableName name of the OVSDB table
114      * @param row the {@link OVSDBRow} Row that is being inserted
115      *
116      * @return Response as dictated by the HTTP Response Status code
117      *
118      * <br>
119      * Examples:
120      * <br>
121      * Create a Bridge Row:
122      * <pre>
123      *
124      * Request URL:
125      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows
126      *
127      * JSON:
128      * {
129      *   "row": {
130      *     "Bridge": {
131      *       "name": "bridge1",
132      *       "datapath_type": "OPENFLOW"
133      *     }
134      *   }
135      * }
136      * </pre>
137      *
138      *
139      * Create a Port Row:
140      * <pre>
141      *
142      * Request URL:
143      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows
144      *
145      * JSON:
146      * {
147      *   "parent_uuid": "b01cd26b-9c63-4216-8cf2-55f7087adab1",
148      *   "row": {
149      *     "Port": {
150      *       "name": "port1",
151      *       "mac": [
152      *         "set",
153      *         "00:00:00:00:00:01"
154      *       ],
155      *       "tag": [
156      *         "set",
157      *         200
158      *       ]
159      *     }
160      *   }
161      * }
162      * </pre>
163      *
164      *
165      * Create an Interface Row:
166      * <pre>
167      *
168      * Request URL:
169      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows
170      *
171      * JSON:
172      * {
173      *   "parent_uuid": "c7b54c9b-9b25-4801-a81d-d7bc489d4840",
174      *   "row": {
175      *     "Interface": {
176      *       "name": "br2",
177      *       "mac": [
178      *         "set",
179      *         "00:00:bb:bb:00:01"
180      *       ],
181      *       "admin_state": "up"
182      *     }
183      *   }
184      * }
185      * </pre>
186      *
187      *
188      * Create an SSL Row:
189      * <pre>
190      *
191      * Request URL:
192      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows
193      *
194      * JSON:
195      * {
196      *   "row": {
197      *     "SSL": {
198      *       "name": "mySSL",
199      *       "ca_cert": "ca_cert",
200      *       "bootstrap_ca_cert": true,
201      *       "certificate": "pieceofpaper",
202      *       "private_key": "private"
203      *     }
204      *   }
205      * }
206      * </pre>
207      *
208      *
209      * Create an sFlow Row:
210      * <pre>
211      *
212      * Request URL:
213      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows
214      *
215      * JSON:
216      * {
217      *   "parent_uuid": "6b3072ba-a120-4db9-82f8-a8ce4eae6942",
218      *   "row": {
219      *     "sFlow": {
220      *       "agent": [
221      *         "set",
222      *         "agent_string"
223      *       ],
224      *       "targets": [
225      *         "set",
226      *         "targets_string"
227      *       ]
228      *     }
229      *   }
230      * }
231      * </pre>
232      *
233      *
234      * Create a QoS Row:
235      * <pre>
236      *
237      * Request URL:
238      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows
239      *
240      * JSON:
241      * {
242      *   "parent_uuid": "b109dbcf-47bb-4121-b244-e623b3421d6e",
243      *   "row": {
244      *     "QoS": {
245      *       "type": "linux-htb"
246      *     }
247      *   }
248      * }
249      * </pre>
250      *
251      *
252      * Create a Queue Row:
253      * <pre>
254      *
255      * Request URL:
256      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows
257      *
258      * {
259      *   "parent_uuid": "b16eae7d-7e97-46d2-95d1-333d1de4a3d7",
260      *   "row": {
261      *     "Queue": {
262      *       "dscp": [
263      *         "set",
264      *         "25"
265      *       ]
266      *     }
267      *   }
268      * }
269      * </pre>
270      *
271      *
272      * Create a Netflow Row:
273      * <pre>
274      *
275      * Request URL:
276      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows
277      *
278      * JSON:
279      * {
280      *   "parent_uuid": "b01cd26b-9c63-4216-8cf2-55f7087adab1",
281      *   "row": {
282      *     "NetFlow": {
283      *       "targets": [
284      *         "set",
285      *         [
286      *           "192.168.1.102:9998"
287      *         ]
288      *       ],
289      *       "active_timeout": "0"
290      *     }
291      *   }
292      * }
293      * </pre>
294      *
295      *
296      * Create a Manager Row:
297      * <pre>
298      *
299      * Request URL:
300      * POST http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows
301      *
302      * JSON:
303      * {
304      *   "parent_uuid": "8d3fb89b-5fac-4631-a990-f5a4e7f5383a",
305      *   "row": {
306      *     "Manager": {
307      *       "target": "a_string",
308      *       "is_connected": true,
309      *       "state": "active"
310      *     }
311      *   }
312      * }
313      * </pre>
314      */
315
316     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows")
317     @POST
318     @StatusCodes({ @ResponseCode(code = 201, condition = "Row Inserted successfully"),
319         @ResponseCode(code = 400, condition = "Invalid data passed"),
320         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
321     @Consumes({ MediaType.APPLICATION_JSON})
322     public Response addRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
323                            @PathParam("tableName") String tableName, @TypeHint(OVSDBRow.class) OVSDBRow row) {
324
325         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
326             throw new UnauthorizedException("User is not authorized to perform this operation");
327         }
328
329         String ovsTableName = getOVSTableName(tableName);
330         if (ovsTableName == null) {
331             Status status = new Status(StatusCode.NOTFOUND, "Table "+tableName+" is not currently supported");
332             return NorthboundUtils.getResponse(status);
333         }
334
335         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
336                                                                                             this);
337         if (ovsdbTable == null) {
338             throw new ServiceUnavailableException("OVS Configuration Service " + RestMessages.SERVICEUNAVAILABLE.toString());
339         }
340
341         if (row != null && row.getRow() != null) {
342             handleNameMismatch(tableName, row.getRow().getTableName().getName());
343             Node node = Node.fromString(nodeType, nodeId);
344             StatusWithUuid statusWithUUID = ovsdbTable.insertRow(node, ovsTableName, row.getParent_uuid(), row.getRow());
345
346             if (statusWithUUID.isSuccess()) {
347                 UUID uuid = statusWithUUID.getUuid();
348                 return Response.status(Response.Status.CREATED)
349                         .header("Location", String.format("%s/%s", _uriInfo.getAbsolutePath().toString(),
350                                                                     uuid.toString()))
351                         .entity(uuid.toString())
352                         .build();
353             } else {
354                 return NorthboundUtils.getResponse(statusWithUUID);
355             }
356         }
357         return Response.status(Response.Status.BAD_REQUEST).build();
358     }
359
360     /**
361      * Read a Row
362      *
363      * @param nodeType type of node e.g OVS
364      * @param nodeId ID of the node
365      * @param tableName name of the ovsdb table
366      * @param rowUuid UUID of the row being read
367      *
368      * @return Row corresponding to the UUID.
369      *
370      * <br>
371      * Examples:
372      * <br>
373      * <pre>
374      * Get a specific Bridge Row:
375      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/6f4c602c-026f-4390-beea-d50d6d448100
376      *
377      * Get a specific Port Row:
378      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows/6f4c602c-026f-4390-beea-d50d6d448100
379      *
380      * Get a specific Interface Row:
381      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows/6f4c602c-026f-4390-beea-d50d6d448100
382      *
383      * Get a specific Controller Row:
384      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows/6f4c602c-026f-4390-beea-d50d6d448100
385      *
386      * Get a specific SSL Row:
387      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows/6f4c602c-026f-4390-beea-d50d6d448100
388      *
389      * Get a specific sFlow Row:
390      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
391      *
392      * Get a specific QoS Row:
393      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/6f4c602c-026f-4390-beea-d50d6d448100
394      *
395      * Get a specific Queue Row:
396      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows/6f4c602c-026f-4390-beea-d50d6d448100
397      *
398      * Get a specific Netflow Row:
399      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
400      *
401      * Get a specific Manager Row:
402      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows/6f4c602c-026f-4390-beea-d50d6d448100
403      * </pre>
404      */
405
406     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{rowUuid}")
407     @GET
408     @StatusCodes({ @ResponseCode(code = 200, condition = "Row Updated successfully"),
409         @ResponseCode(code = 400, condition = "Invalid data passed"),
410         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
411     @Consumes({ MediaType.APPLICATION_JSON})
412     @TypeHint(OVSDBRow.class)
413     public OVSDBRow getRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
414                            @PathParam("tableName") String tableName, @PathParam("rowUuid") String rowUuid) {
415
416         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
417             throw new UnauthorizedException("User is not authorized to perform this operation");
418         }
419
420         String ovsTableName = getOVSTableName(tableName);
421         if (ovsTableName == null) return null;
422
423         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
424                                                                                             this);
425         if (ovsdbTable == null) {
426             throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
427         }
428
429         Node node = Node.fromString(nodeType, nodeId);
430         Table<?> row = null;
431         try {
432             row = ovsdbTable.getRow(node, ovsTableName, rowUuid);
433         } catch (Exception e) {
434             throw new BadRequestException(e.getMessage());
435         }
436         return new OVSDBRow(null, row);
437     }
438
439     /**
440      * Read all Rows of a table
441      *
442      * @param nodeType type of node e.g OVS
443      * @param nodeId ID of the node
444      * @param tableName name of the ovsdb table
445      *
446      * @return All the Rows of a table
447      *
448      * <br>
449      * Examples:
450      * <br>
451      * <pre>
452      * Get all Bridge Rows:
453      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows
454      *
455      * Get all Port Rows:
456      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows
457      *
458      * Get all Interface Rows:
459      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows
460      *
461      * Get all Controller Rows:
462      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows
463      *
464      * Get all SSL Rows:
465      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows
466      *
467      * Get all sFlow Rows:
468      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows
469      *
470      * Get all QoS Rows:
471      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows
472      *
473      * Get all Queue Rows:
474      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows
475      *
476      * Get all Netflow Rows:
477      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows
478      *
479      * Get all Manager Rows:
480      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows
481      *
482      * Get all Open vSwitch Rows:
483      * GET http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/open_vswitch/rows
484      * </pre>
485      */
486
487     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows")
488     @GET
489     @StatusCodes({ @ResponseCode(code = 200, condition = "Row Updated successfully"),
490         @ResponseCode(code = 400, condition = "Invalid data passed"),
491         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
492     @Consumes({ MediaType.APPLICATION_JSON})
493     @TypeHint(OVSDBRows.class)
494     public OVSDBRows getAllRows(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
495                                @PathParam("tableName") String tableName) {
496         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
497             throw new UnauthorizedException("User is not authorized to perform this operation");
498         }
499
500         String ovsTableName = getOVSTableName(tableName);
501         if (ovsTableName == null) return null;
502
503         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
504                                                                                             this);
505         if (ovsdbTable == null) {
506             throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
507         }
508
509         Node node = Node.fromString(nodeType, nodeId);
510         Map<String, Table<?>> rows = null;
511         try {
512             rows = ovsdbTable.getRows(node, ovsTableName);
513         } catch (Exception e) {
514             throw new BadRequestException(e.getMessage());
515         }
516         return new OVSDBRows(rows);
517     }
518
519     /**
520      * Update a Row
521      *
522      * @param nodeType type of node e.g OVS
523      * @param nodeId ID of the node
524      * @param tableName name of the ovsdb table
525      * @param rowUuid UUID of the row being updated
526      * @param row the {@link OVSDBRow} Row that is being updated
527      *
528      * @return Response as dictated by the HTTP Response Status code
529      *
530      * <br>
531      * Examples:
532      * <br>
533      * Update the Bridge row to add a controller
534      * <pre>
535      *
536      * Request URL:
537      * PUT http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/b01cd26b-9c63-4216-8cf2-55f7087adab1
538      *
539      * JSON:
540      * {
541      *   "row": {
542      *     "Bridge": {
543      *       "controller": [
544      *         "set",
545      *         [
546      *           [
547      *             "uuid",
548      *             "a566e8b4-fc38-499b-8623-6087d5b36b72"
549      *           ]
550      *         ]
551      *       ]
552      *     }
553      *   }
554      * }
555      * </pre>
556      */
557
558     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{rowUuid}")
559     @PUT
560     @StatusCodes({ @ResponseCode(code = 200, condition = "Row Updated successfully"),
561         @ResponseCode(code = 400, condition = "Invalid data passed"),
562         @ResponseCode(code = 401, condition = "User not authorized to perform this operation")})
563     @Consumes({ MediaType.APPLICATION_JSON})
564     public Response updateRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
565                            @PathParam("tableName") String tableName, @PathParam("rowUuid") String rowUuid,
566                            @TypeHint(OVSDBRow.class) OVSDBRow row) {
567
568         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
569             throw new UnauthorizedException("User is not authorized to perform this operation");
570         }
571
572         String ovsTableName = getOVSTableName(tableName);
573         if (ovsTableName == null) {
574             Status status = new Status(StatusCode.NOTFOUND, "Table "+tableName+" is not currently supported");
575             return NorthboundUtils.getResponse(status);
576         }
577
578         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class,
579                                                                                             this);
580         if (ovsdbTable == null) {
581             throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
582         }
583
584         if (row != null && row.getRow() != null) {
585             handleNameMismatch(tableName, row.getRow().getTableName().getName());
586             Node node = Node.fromString(nodeType, nodeId);
587             Status status = ovsdbTable.updateRow(node, ovsTableName, row.getParent_uuid(), rowUuid, row.getRow());
588             return NorthboundUtils.getResponse(status);
589         }
590         return Response.status(Response.Status.BAD_REQUEST).build();
591     }
592
593     /**
594      * Delete a row
595      *
596      * @param nodeType type of node e.g OVS
597      * @param nodeId ID of the node
598      * @param tableName name of the ovsdb table
599      * @param uuid UUID of the Row to be removed
600      *
601      * @return Response as dictated by the HTTP Response Status code
602      *
603      * <br>
604      * Examples:
605      * <br>
606      * <pre>
607      * Delete a specific Bridge Row:
608      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/bridge/rows/6f4c602c-026f-4390-beea-d50d6d448100
609      *
610      * Delete a specific Port Row:
611      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/port/rows/6f4c602c-026f-4390-beea-d50d6d448100
612      *
613      * Delete a specific Interface Row:
614      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/interface/rows/6f4c602c-026f-4390-beea-d50d6d448100
615      *
616      * Delete a specific Controller Row:
617      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/controller/rows/6f4c602c-026f-4390-beea-d50d6d448100
618      *
619      * Delete a specific SSL Row:
620      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/SSL/rows/6f4c602c-026f-4390-beea-d50d6d448100
621      *
622      * Delete a specific sFlow Row:
623      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/sflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
624      *
625      * Delete a specific QoS Row:
626      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/qos/rows/6f4c602c-026f-4390-beea-d50d6d448100
627      *
628      * Delete a specific Queue Row:
629      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/queue/rows/6f4c602c-026f-4390-beea-d50d6d448100
630      *
631      * Delete a specific Netflow Row:
632      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/netflow/rows/6f4c602c-026f-4390-beea-d50d6d448100
633      *
634      * Delete a specific Manager Row:
635      * DELETE http://localhost:8080/ovsdb/nb/v2/node/OVS/HOST1/tables/manager/rows/6f4c602c-026f-4390-beea-d50d6d448100
636      * </pre>
637      */
638     @Path("/node/{nodeType}/{nodeId}/tables/{tableName}/rows/{uuid}")
639     @DELETE
640     @StatusCodes({ @ResponseCode(code = 204, condition = "User Deleted Successfully"),
641         @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
642         @ResponseCode(code = 404, condition = "The userName passed was not found"),
643         @ResponseCode(code = 500, condition = "Internal Server Error : Removal of user failed"),
644         @ResponseCode(code = 503, condition = "Service unavailable") })
645     public Response removeRow(@PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId,
646                               @PathParam("tableName") String tableName, @PathParam("uuid") String uuid) {
647         if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) {
648             throw new UnauthorizedException("User is not authorized to perform this operation");
649         }
650
651         String ovsTableName = getOVSTableName(tableName);
652         if (ovsTableName == null) {
653             Status status = new Status(StatusCode.NOTFOUND, "Table "+tableName+" is not currently supported");
654             return NorthboundUtils.getResponse(status);
655         }
656
657         OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
658         if (ovsdbTable == null) {
659             throw new ServiceUnavailableException("UserManager " + RestMessages.SERVICEUNAVAILABLE.toString());
660         }
661         Node node = Node.fromString(nodeType, nodeId);
662         Status status = ovsdbTable.deleteRow(node, ovsTableName, uuid);
663         if (status.isSuccess()) {
664             return Response.noContent().build();
665         }
666         return NorthboundUtils.getResponse(status);
667     }
668 }