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