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