Merge changes Iec115491,I5b6f87c7,I6c05abf0
[netvirt.git] / plugin / src / main / java / org / opendaylight / ovsdb / plugin / impl / ConfigurationServiceImpl.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc.
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, Keith Burns
9  */
10 package org.opendaylight.ovsdb.plugin.impl;
11
12 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
13
14 import java.net.InetAddress;
15 import java.net.UnknownHostException;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.concurrent.ConcurrentMap;
23 import java.util.concurrent.ExecutionException;
24
25 import org.eclipse.osgi.framework.console.CommandInterpreter;
26 import org.eclipse.osgi.framework.console.CommandProvider;
27 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
28 import org.opendaylight.controller.sal.connection.ConnectionConstants;
29 import org.opendaylight.controller.sal.core.Node;
30 import org.opendaylight.controller.sal.core.NodeConnector;
31 import org.opendaylight.controller.sal.networkconfig.bridgedomain.ConfigConstants;
32 import org.opendaylight.controller.sal.networkconfig.bridgedomain.IPluginInBridgeDomainConfigService;
33 import org.opendaylight.controller.sal.utils.Status;
34 import org.opendaylight.controller.sal.utils.StatusCode;
35 import org.opendaylight.ovsdb.lib.OvsdbClient;
36 import org.opendaylight.ovsdb.lib.error.SchemaVersionMismatchException;
37 import org.opendaylight.ovsdb.lib.notation.Column;
38 import org.opendaylight.ovsdb.lib.notation.Mutator;
39 import org.opendaylight.ovsdb.lib.notation.OvsdbSet;
40 import org.opendaylight.ovsdb.lib.notation.Row;
41 import org.opendaylight.ovsdb.lib.notation.UUID;
42 import org.opendaylight.ovsdb.lib.operations.Insert;
43 import org.opendaylight.ovsdb.lib.operations.Operation;
44 import org.opendaylight.ovsdb.lib.operations.OperationResult;
45 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
46 import org.opendaylight.ovsdb.lib.schema.ColumnSchema;
47 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
48 import org.opendaylight.ovsdb.lib.schema.GenericTableSchema;
49 import org.opendaylight.ovsdb.lib.schema.TableSchema;
50 import org.opendaylight.ovsdb.lib.schema.typed.TypedBaseTable;
51 import org.opendaylight.ovsdb.plugin.OvsdbConfigService;
52 import org.opendaylight.ovsdb.plugin.api.Connection;
53 import org.opendaylight.ovsdb.plugin.api.OvsVswitchdSchemaConstants;
54 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
55 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
56 import org.opendaylight.ovsdb.plugin.api.OvsdbInventoryService;
57 import org.opendaylight.ovsdb.plugin.api.StatusWithUuid;
58 import org.opendaylight.ovsdb.plugin.error.OvsdbPluginException;
59 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
60 import org.opendaylight.ovsdb.schema.openvswitch.Controller;
61 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
62 import org.opendaylight.ovsdb.schema.openvswitch.Manager;
63 import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
64 import org.opendaylight.ovsdb.schema.openvswitch.Port;
65 import org.osgi.framework.BundleContext;
66 import org.osgi.framework.FrameworkUtil;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
69
70 import com.google.common.collect.ImmutableSet;
71 import com.google.common.util.concurrent.ListenableFuture;
72
73 public class ConfigurationServiceImpl implements IPluginInBridgeDomainConfigService,
74                                                  OvsdbConfigurationService,
75                                                  OvsdbConfigService,
76                                                  CommandProvider
77 {
78     private static final Logger logger = LoggerFactory
79             .getLogger(ConfigurationServiceImpl.class);
80
81     OvsdbConnectionService connectionService;
82     OvsdbInventoryService ovsdbInventoryService;
83     boolean forceConnect = false;
84     protected static final String OPENFLOW_10 = "1.0";
85     protected static final String OPENFLOW_13 = "1.3";
86
87     void init() {
88     }
89
90     /**
91      * Function called by the dependency manager when at least one dependency
92      * become unsatisfied or when the component is shutting down because for
93      * example bundle is being stopped.
94      *
95      */
96     void destroy() {
97     }
98
99     /**
100      * Function called by dependency manager after "init ()" is called and after
101      * the services provided by the class are registered in the service registry
102      *
103      */
104     void start() {
105         registerWithOSGIConsole();
106     }
107
108     private void registerWithOSGIConsole() {
109         BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass())
110                 .getBundleContext();
111         bundleContext.registerService(CommandProvider.class.getName(), this,
112                 null);
113     }
114
115     /**
116      * Function called by the dependency manager before the services exported by
117      * the component are unregistered, this will be followed by a "destroy ()"
118      * calls
119      *
120      */
121     void stop() {
122     }
123
124     public void setConnectionServiceInternal(OvsdbConnectionService connectionService) {
125         this.connectionService = connectionService;
126     }
127
128     public void unsetConnectionServiceInternal(OvsdbConnectionService connectionService) {
129         if (this.connectionService == connectionService) {
130             this.connectionService = null;
131         }
132     }
133
134     public void setOvsdbInventoryService(OvsdbInventoryService ovsdbInventoryService) {
135         this.ovsdbInventoryService = ovsdbInventoryService;
136     }
137
138     public void unsetInventoryServiceInternal(OvsdbInventoryService ovsdbInventoryService) {
139         if (this.ovsdbInventoryService == ovsdbInventoryService) {
140             this.ovsdbInventoryService = null;
141         }
142     }
143
144     private IClusterGlobalServices clusterServices;
145
146     public void setClusterServices(IClusterGlobalServices i) {
147         this.clusterServices = i;
148     }
149
150     public void unsetClusterServices(IClusterGlobalServices i) {
151         if (this.clusterServices == i) {
152             this.clusterServices = null;
153         }
154     }
155
156     private Connection getConnection (Node node) {
157         Connection connection = connectionService.getConnection(node);
158         if (connection == null || !connection.getClient().isActive()) {
159             return null;
160         }
161
162         return connection;
163     }
164     /*
165      * There are a few Open_vSwitch schema specific special case handling to be done for
166      * the older API (such as by inserting a mandatory Interface row automatically upon inserting
167      * a Port row.
168      */
169     private void handleSpecialInsertCase(OvsdbClient client, String databaseName,
170             String tableName, String uuid, Row<GenericTableSchema> row, TransactionBuilder transactionBuilder) {
171         Port port = client.getTypedRowWrapper(Port.class, null);
172         if (databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME) && tableName.equals(port.getSchema().getName())) {
173             port = client.getTypedRowWrapper(Port.class, row);
174             DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
175             TableSchema<GenericTableSchema> tableSchema = dbSchema.table(tableName, GenericTableSchema.class);
176             ColumnSchema<GenericTableSchema, Set<UUID>> columnSchema = tableSchema.multiValuedColumn("interfaces", UUID.class);
177             String namedUuid = "Special_"+tableName;
178             List<Operation> priorOperations = transactionBuilder.getOperations();
179             Insert portOperation = (Insert)priorOperations.get(0);
180             portOperation.value(columnSchema, new UUID(namedUuid));
181
182             Column<GenericTableSchema, ?> nameColumn = port.getNameColumn();
183             List<Column<GenericTableSchema, ?>> columns = new ArrayList<Column<GenericTableSchema, ?>>();
184             columns.add(nameColumn);
185             Row<GenericTableSchema> intfRow = new Row<GenericTableSchema>(tableSchema, columns);
186             this.processInsertTransaction(client, databaseName, "Interface", null, null, null, namedUuid, intfRow, transactionBuilder);
187         }
188     }
189
190     /*
191      * A common Transaction that takes in old API style Parent_uuid and inserts a mutation on
192      * the parent table for the newly inserted Child.
193      * Due to some additional special case(s), the Transaction is further amended by handleSpecialInsertCase
194      */
195     private void processInsertTransaction(OvsdbClient client, String databaseName, String childTable,
196                                     String parentTable, String parentUuid, String parentColumn, String namedUuid,
197                                     Row<GenericTableSchema> row, TransactionBuilder transactionBuilder) {
198         DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
199         TableSchema<GenericTableSchema> childTableSchema = dbSchema.table(childTable, GenericTableSchema.class);
200         transactionBuilder.add(op.insert(childTableSchema, row)
201                         .withId(namedUuid));
202
203         if (parentColumn != null) {
204             TableSchema<GenericTableSchema> parentTableSchema = dbSchema.table(parentTable, GenericTableSchema.class);
205             ColumnSchema<GenericTableSchema, UUID> parentColumnSchema = parentTableSchema.column(parentColumn, UUID.class);
206             ColumnSchema<GenericTableSchema, UUID> _uuid = parentTableSchema.column("_uuid", UUID.class);
207
208             transactionBuilder
209                 .add(op.mutate(parentTableSchema)
210                         .addMutation(parentColumnSchema, Mutator.INSERT, new UUID(namedUuid))
211                         .where(_uuid.opEqual(new UUID(parentUuid)))
212                         .build());
213         }
214         /*
215          * There are a few Open_vSwitch schema specific special case handling to be done for
216          * the older API (such as by inserting a mandatory Interface row automatically upon inserting
217          * a Port row.
218          */
219         handleSpecialInsertCase(client, databaseName, childTable, namedUuid, row, transactionBuilder);
220     }
221
222     /*
223      * TODO : Move all the Special Cases out of ConfigurationService and into the Schema specific bundles.
224      * But that makes plugin more reliant on the Typed Bundles more than just API wrapper.
225      * Keeping these Special Handling locally till we introduce the full schema independent APIs in the
226      * plugin layer.
227      */
228     public String getSpecialCaseParentUUID(Node node, String databaseName, String childTableName) {
229         if (!databaseName.equals(OvsVswitchdSchemaConstants.DATABASE_NAME)) return null;
230         String[] parentColumn = OvsVswitchdSchemaConstants.getParentColumnToMutate(childTableName);
231         if (parentColumn != null && parentColumn[0].equals(OvsVswitchdSchemaConstants.DATABASE_NAME)) {
232             Connection connection = connectionService.getConnection(node);
233             OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null);
234             ConcurrentMap<String, Row> row = this.getRows(node, openVSwitch.getSchema().getName());
235             if (row == null || row.size() == 0) return null;
236             return (String)row.keySet().toArray()[0];
237         }
238         return null;
239     }
240
241     /*
242      * Though this is a New API that takes in Row object, this still is considered a
243      * Deprecated call because of the assumption with a Single Row insertion.
244      * An ideal insertRow must be able to take in multiple Rows, which includes the
245      * Row being inserted in one Table and other Rows that needs mutate in other Tables.
246      */
247     @Override
248     public StatusWithUuid insertRow(Node node, String tableName, String parentUuid, Row<GenericTableSchema> row) {
249         String[] parentColumn = OvsVswitchdSchemaConstants.getParentColumnToMutate(tableName);
250         if (parentColumn == null) {
251             parentColumn = new String[]{null, null};
252         }
253
254         Connection connection = connectionService.getConnection(node);
255         OvsdbClient client = connection.getClient();
256
257         if (parentUuid == null) {
258             parentUuid = this.getSpecialCaseParentUUID(node, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName);
259         }
260         logger.debug("insertRow Connection : {} Table : {} ParentTable : {} Parent Column: {} Parent UUID : {} Row : {}",
261                      client.getConnectionInfo(), tableName, parentColumn[0], parentColumn[1], parentUuid, row);
262
263         DatabaseSchema dbSchema = client.getDatabaseSchema(OvsVswitchdSchemaConstants.DATABASE_NAME);
264         TransactionBuilder transactionBuilder = client.transactBuilder(dbSchema);
265
266         String namedUuid = "Transaction_"+ tableName;
267         this.processInsertTransaction(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName,
268                                 parentColumn[0], parentUuid, parentColumn[1], namedUuid,
269                                 row, transactionBuilder);
270
271         ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
272         List<OperationResult> operationResults;
273         try {
274             operationResults = results.get();
275             if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) {
276                 return new StatusWithUuid(StatusCode.INTERNALERROR);
277             }
278             for (OperationResult result : operationResults) {
279                 if (result.getError() != null) {
280                     return new StatusWithUuid(StatusCode.BADREQUEST, result.getError());
281                 }
282             }
283             UUID uuid = operationResults.get(0).getUuid();
284             return new StatusWithUuid(StatusCode.SUCCESS, uuid);
285         } catch (InterruptedException | ExecutionException e) {
286             // TODO Auto-generated catch block
287             return new StatusWithUuid(StatusCode.INTERNALERROR, e.getLocalizedMessage());
288         }
289
290     }
291
292     @Override
293     public Status updateRow (Node node, String tableName, String parentUUID, String rowUUID, Row row) {
294         String databaseName = OvsVswitchdSchemaConstants.DATABASE_NAME;
295         Connection connection = connectionService.getConnection(node);
296         OvsdbClient client = connection.getClient();
297
298         logger.debug("updateRow : Connection : {} databaseName : {} tableName : {} rowUUID : {} row : {}",
299                       client.getConnectionInfo(), databaseName, tableName, rowUUID, row.toString());
300         try{
301             DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
302             TransactionBuilder transactionBuilder = client.transactBuilder(dbSchema);
303             TableSchema<GenericTableSchema> tableSchema = dbSchema.table(tableName, GenericTableSchema.class);
304             ColumnSchema<GenericTableSchema, UUID> _uuid = tableSchema.column("_uuid", UUID.class);
305             transactionBuilder.add(op.update(tableSchema, row)
306                                      .where(_uuid.opEqual(new UUID(rowUUID)))
307                                      .build());
308
309             ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
310             List<OperationResult> operationResults = results.get();
311             if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) {
312                 return new StatusWithUuid(StatusCode.INTERNALERROR);
313             }
314             for (OperationResult result : operationResults) {
315                 if (result.getError() != null) {
316                     return new StatusWithUuid(StatusCode.BADREQUEST, result.getError());
317                 }
318             }
319             return new StatusWithUuid(StatusCode.SUCCESS);
320         } catch(Exception e){
321             logger.error("Error in updateRow(): ",e);
322         }
323         return new Status(StatusCode.INTERNALERROR);
324     }
325
326     private void processDeleteTransaction(OvsdbClient client, String databaseName, String childTable,
327                                     String parentTable, String parentColumn, String uuid, TransactionBuilder transactionBuilder) {
328         DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
329         TableSchema<GenericTableSchema> childTableSchema = dbSchema.table(childTable, GenericTableSchema.class);
330
331         if (parentColumn != null) {
332             TableSchema<GenericTableSchema> parentTableSchema = dbSchema.table(parentTable, GenericTableSchema.class);
333             ColumnSchema<GenericTableSchema, UUID> parentColumnSchema = parentTableSchema.column(parentColumn, UUID.class);
334             transactionBuilder
335                 .add(op.mutate(parentTableSchema)
336                         .addMutation(parentColumnSchema, Mutator.DELETE, new UUID(uuid))
337                         .where(parentColumnSchema.opIncludes(new UUID(uuid)))
338                         .build());
339         }
340
341         ColumnSchema<GenericTableSchema, UUID> _uuid = childTableSchema.column("_uuid", UUID.class);
342         transactionBuilder.add(op.delete(childTableSchema)
343                 .where(_uuid.opEqual(new UUID(uuid)))
344                 .build());
345     }
346
347     @Override
348     public Status deleteRow(Node node, String tableName, String uuid) {
349         String databaseName = OvsVswitchdSchemaConstants.DATABASE_NAME;
350         Connection connection = connectionService.getConnection(node);
351         OvsdbClient client = connection.getClient();
352
353         String[] parentColumn = OvsVswitchdSchemaConstants.getParentColumnToMutate(tableName);
354         if (parentColumn == null) {
355             parentColumn = new String[]{null, null};
356         }
357
358         logger.debug("deleteRow : Connection : {} databaseName : {} tableName : {} Uuid : {} ParentTable : {} ParentColumn : {}",
359                 client.getConnectionInfo(), databaseName, tableName, uuid, parentColumn[0], parentColumn[1]);
360
361         DatabaseSchema dbSchema = client.getDatabaseSchema(databaseName);
362         TransactionBuilder transactionBuilder = client.transactBuilder(dbSchema);
363         this.processDeleteTransaction(client, OvsVswitchdSchemaConstants.DATABASE_NAME, tableName,
364                                       parentColumn[0], parentColumn[1], uuid, transactionBuilder);
365
366         ListenableFuture<List<OperationResult>> results = transactionBuilder.execute();
367         List<OperationResult> operationResults;
368         try {
369             operationResults = results.get();
370             if (operationResults.isEmpty() || (transactionBuilder.getOperations().size() != operationResults.size())) {
371                 return new StatusWithUuid(StatusCode.INTERNALERROR);
372             }
373             for (OperationResult result : operationResults) {
374                 if (result.getError() != null) {
375                     return new StatusWithUuid(StatusCode.BADREQUEST, result.getError());
376                 }
377             }
378         } catch (InterruptedException | ExecutionException e) {
379             // TODO Auto-generated catch block
380             e.printStackTrace();
381         }
382
383         return new Status(StatusCode.SUCCESS);
384     }
385
386     @Override
387     public ConcurrentMap<String, Row> getRows(Node node, String tableName) {
388         ConcurrentMap<String, Row> ovsTable = ovsdbInventoryService.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME,  tableName);
389         return ovsTable;
390     }
391
392     @Override
393     public Row getRow(Node node, String tableName, String uuid) {
394         Map<String, Row> ovsTable = ovsdbInventoryService.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME,  tableName);
395         if (ovsTable == null) return null;
396         return ovsTable.get(uuid);
397     }
398
399     @Override
400     public List<String> getTables(Node node) {
401         ConcurrentMap<String, ConcurrentMap<String, Row>> cache  = ovsdbInventoryService.getCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME);
402         if (cache == null) return null;
403         return new ArrayList<String>(cache.keySet());
404     }
405
406     private List<InetAddress> getControllerIPAddresses(Connection connection) {
407         List<InetAddress> controllers = null;
408         InetAddress controllerIP = null;
409
410         controllers = new ArrayList<InetAddress>();
411         String addressString = System.getProperty("ovsdb.controller.address");
412
413         if (addressString != null) {
414             try {
415                 controllerIP = InetAddress.getByName(addressString);
416                 if (controllerIP != null) {
417                     controllers.add(controllerIP);
418                     return controllers;
419                 }
420             } catch (UnknownHostException e) {
421                 logger.error("Host {} is invalid", addressString);
422             }
423         }
424
425         if (clusterServices != null) {
426             controllers = clusterServices.getClusteredControllers();
427             if (controllers != null && controllers.size() > 0) {
428                 if (controllers.size() == 1) {
429                     InetAddress controller = controllers.get(0);
430                     if (!controller.equals(InetAddress.getLoopbackAddress())) {
431                         return controllers;
432                     }
433                 } else {
434                     return controllers;
435                 }
436             }
437         }
438
439         addressString = System.getProperty("of.address");
440
441         if (addressString != null) {
442             try {
443                 controllerIP = InetAddress.getByName(addressString);
444                 if (controllerIP != null) {
445                     controllers.add(controllerIP);
446                     return controllers;
447                 }
448             } catch (UnknownHostException e) {
449                 logger.error("Host {} is invalid", addressString);
450             }
451         }
452
453         try {
454             controllerIP = connection.getClient().getConnectionInfo().getLocalAddress();
455             controllers.add(controllerIP);
456             return controllers;
457         } catch (Exception e) {
458             logger.debug("Invalid connection provided to getControllerIPAddresses", e);
459         }
460         return controllers;
461     }
462
463     private short getControllerOFPort() {
464         Short defaultOpenFlowPort = 6633;
465         Short openFlowPort = defaultOpenFlowPort;
466         String portString = System.getProperty("of.listenPort");
467         if (portString != null) {
468             try {
469                 openFlowPort = Short.decode(portString).shortValue();
470             } catch (NumberFormatException e) {
471                 logger.warn("Invalid port:{}, use default({})", portString,
472                         openFlowPort);
473             }
474         }
475         return openFlowPort;
476     }
477
478     @Override
479     public Boolean setOFController(Node node, String bridgeUUID) throws InterruptedException, ExecutionException {
480         Connection connection = this.getConnection(node);
481         if (connection == null) {
482             return false;
483         }
484
485         Bridge bridge = connection.getClient().createTypedRowWrapper(Bridge.class);
486
487         Status updateOperationStatus = null;
488         try {
489             OvsdbSet<String> protocols = new OvsdbSet<String>();
490
491             String ofVersion = System.getProperty("ovsdb.of.version", OPENFLOW_10);
492             switch (ofVersion) {
493                 case OPENFLOW_13:
494                     protocols.add("OpenFlow13");
495                     break;
496                 case OPENFLOW_10:
497                     //fall through
498                 default:
499                     protocols.add("OpenFlow10");
500                     break;
501             }
502             bridge.setProtocols(protocols);
503             updateOperationStatus = this.updateRow(node, bridge.getSchema().getName(),
504                                                    null, bridgeUUID, bridge.getRow());
505             logger.debug("Bridge {} updated to {} with Status {}", bridgeUUID,
506                          protocols.toArray()[0],updateOperationStatus);
507
508         } catch (SchemaVersionMismatchException e){
509             logger.debug(e.toString());
510         }
511
512         // If we fail to update the protocols
513         if (updateOperationStatus != null && !updateOperationStatus.isSuccess()) {
514             return updateOperationStatus.isSuccess();
515         }
516
517         Status status = null;
518         List<InetAddress> ofControllerAddrs = this.getControllerIPAddresses(connection);
519         short ofControllerPort = getControllerOFPort();
520         for (InetAddress ofControllerAddress : ofControllerAddrs) {
521             String newController = "tcp:"+ofControllerAddress.getHostAddress()+":"+ofControllerPort;
522             Controller controllerRow = connection.getClient().createTypedRowWrapper(Controller.class);
523             controllerRow.setTarget(newController);
524             //ToDo: Status gets overwritten on each iteration. If any operation other than the last fails it's ignored.
525             status = this.insertRow(node, controllerRow.getSchema().getName(), bridgeUUID, controllerRow.getRow());
526         }
527
528         if (status != null) {
529             return status.isSuccess();
530         }
531
532         return false;
533     }
534
535
536     public Boolean setBridgeOFController(Node node, String bridgeIdentifier) {
537         if (connectionService == null) {
538             logger.error("Couldn't refer to the ConnectionService");
539             return false;
540         }
541
542         try{
543             Connection connection = connectionService.getConnection(node);
544             Bridge bridge = connection.getClient().getTypedRowWrapper(Bridge.class, null);
545
546             Map<String, Row> brTableCache = ovsdbInventoryService.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME, bridge.getSchema().getName());
547             for (String uuid : brTableCache.keySet()) {
548                 bridge = connection.getClient().getTypedRowWrapper(Bridge.class, brTableCache.get(uuid));
549                 if (bridge.getName().contains(bridgeIdentifier)) {
550                     return setOFController(node, uuid);
551                 }
552             }
553         } catch(Exception e) {
554             logger.error("Error in setBridgeOFController()",e);
555         }
556         return false;
557     }
558
559     @Override
560     public <T extends TypedBaseTable<?>> String getTableName(Node node, Class<T> typedClass) {
561         Connection connection = connectionService.getConnection(node);
562         if (connection == null) return null;
563         OvsdbClient client = connection.getClient();
564         TypedBaseTable<?> typedTable = client.getTypedRowWrapper(typedClass, null);
565         if (typedTable == null) return null;
566         return typedTable.getSchema().getName();
567     }
568
569     @Override
570     public <T extends TypedBaseTable<?>> T getTypedRow(Node node, Class<T> typedClass, Row row) {
571         Connection connection = connectionService.getConnection(node);
572         if (connection == null) return null;
573         OvsdbClient client = connection.getClient();
574         return (T)client.getTypedRowWrapper(typedClass, row);
575     }
576
577     @Override
578     public <T extends TypedBaseTable<?>> T createTypedRow(Node node, Class<T> typedClass) {
579         Connection connection = connectionService.getConnection(node);
580         if (connection == null) return null;
581         OvsdbClient client = connection.getClient();
582         return client.createTypedRowWrapper(typedClass);
583     }
584
585     public void _ovsconnect (CommandInterpreter ci) {
586         String bridgeName = ci.nextArgument();
587         if (bridgeName == null) {
588             ci.println("Please enter Bridge Name");
589             return;
590         }
591
592         String ovsdbserver = ci.nextArgument();
593         if (ovsdbserver == null) {
594             ci.println("Please enter valid IP-Address");
595             return;
596         }
597         try {
598             InetAddress.getByName(ovsdbserver);
599         }  catch (UnknownHostException e) {
600             logger.error("Unable to resolve " + ovsdbserver, e);
601             ci.println("Please enter valid IP-Address");
602             return;
603         }
604         String port = ci.nextArgument();
605         if (port == null) {
606             port = "6634";
607         }
608
609         ci.println("connecting to ovsdb server : "+ovsdbserver+":"+port+" ... ");
610         Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
611         params.put(ConnectionConstants.ADDRESS, ovsdbserver);
612         params.put(ConnectionConstants.PORT, port);
613         Node node = connectionService.connect(bridgeName, params);
614         if (node != null) ci.println("Node Name: "+node.toString());
615         else ci.println("Could not connect to Node");
616     }
617
618     public void _addBridge (CommandInterpreter ci) {
619         String nodeName = ci.nextArgument();
620         if (nodeName == null) {
621             ci.println("Please enter Node Name");
622             return;
623         }
624         String bridgeName = ci.nextArgument();
625         if (bridgeName == null) {
626             ci.println("Please enter Bridge Name");
627             return;
628         }
629         Status status;
630
631         Node node = Node.fromString(nodeName);
632         if (node == null) {
633             ci.println("Invalid Node");
634             return;
635         }
636         status = this.createBridgeDomain(node, bridgeName, null);
637         ci.println("Bridge creation status : "+status.toString());
638     }
639
640     public void _getBridgeDomains (CommandInterpreter ci) {
641         String nodeName = ci.nextArgument();
642         if (nodeName == null) {
643             ci.println("Please enter Node Name");
644             return;
645         }
646
647         List<String> brlist = new ArrayList<String>();
648         Node node = Node.fromString(nodeName);
649         brlist = this.getBridgeDomains(node);
650         if (node == null) {
651             ci.println("Invalid Node");
652             return;
653         }
654         ci.println("Existing Bridges: "+brlist.toString());
655     }
656
657     public void _deleteBridgeDomain (CommandInterpreter ci) {
658         String nodeName = ci.nextArgument();
659         if (nodeName == null) {
660             ci.println("Please enter Node Name");
661             return;
662         }
663         String bridgeName = ci.nextArgument();
664         if (bridgeName == null) {
665             ci.println("Please enter Bridge Name");
666             return;
667         }
668         Status status;
669         Node node = Node.fromString(nodeName);
670         if (node == null) {
671             ci.println("Invalid Node");
672             return;
673         }
674         status = this.deleteBridgeDomain(node, bridgeName);
675         ci.println("Bridge deletion status : "+status.toString());
676     }
677
678     public void _addPort (CommandInterpreter ci) {
679         String nodeName = ci.nextArgument();
680         if (nodeName == null) {
681             ci.println("Please enter Node Name");
682             return;
683         }
684
685         String bridgeName = ci.nextArgument();
686         if (bridgeName == null) {
687             ci.println("Please enter Bridge Name");
688             return;
689         }
690
691         String portName = ci.nextArgument();
692         if (portName == null) {
693             ci.println("Please enter Port Name");
694             return;
695         }
696
697         String type = ci.nextArgument();
698
699         Map<String, String> configs = new HashMap<String, String>();
700         while(true) {
701             String configKey = ci.nextArgument();
702             if (configKey == null) break;
703             String configValue = ci.nextArgument();
704             if (configValue == null) break;
705             configs.put(configKey, configValue);
706         }
707
708         Map<ConfigConstants, Object> customConfigs = null;
709         if (type != null) {
710             customConfigs = new HashMap<ConfigConstants, Object>();
711             customConfigs.put(ConfigConstants.TYPE, type);
712         }
713
714         if (configs.size() > 0) {
715             if (customConfigs == null) customConfigs = new HashMap<ConfigConstants, Object>();
716             customConfigs.put(ConfigConstants.CUSTOM, configs);
717             ci.println(customConfigs.toString());
718         }
719         Status status;
720         Node node = Node.fromString(nodeName);
721         if (node == null) {
722             ci.println("Invalid Node");
723             return;
724         }
725         status = this.addPort(node, bridgeName, portName, customConfigs);
726         ci.println("Port creation status : "+status.toString());
727     }
728
729     public void _deletePort (CommandInterpreter ci) {
730         String nodeName = ci.nextArgument();
731         if (nodeName == null) {
732             ci.println("Please enter Node Name");
733             return;
734         }
735
736         String bridgeName = ci.nextArgument();
737         if (bridgeName == null) {
738             ci.println("Please enter Bridge Name");
739             return;
740         }
741
742         String portName = ci.nextArgument();
743         if (portName == null) {
744             ci.println("Please enter Port Name");
745             return;
746         }
747
748         Status status;
749         Node node = Node.fromString(nodeName);
750         if (node == null) {
751             ci.println("Invalid Node");
752             return;
753         }
754         status = this.deletePort(node, bridgeName, portName);
755         ci.println("Port deletion status : "+status.toString());
756     }
757
758     public void _addPortVlan (CommandInterpreter ci) {
759         String nodeName = ci.nextArgument();
760         if (nodeName == null) {
761             ci.println("Please enter Node Name");
762             return;
763         }
764
765         String bridgeName = ci.nextArgument();
766         if (bridgeName == null) {
767             ci.println("Please enter Bridge Name");
768             return;
769         }
770
771         String portName = ci.nextArgument();
772         if (portName == null) {
773             ci.println("Please enter Port Name");
774             return;
775         }
776
777         String vlan = ci.nextArgument();
778         if (vlan == null) {
779             ci.println("Please enter Valid Vlan");
780             return;
781         } else {
782             try {
783             Integer.parseInt(vlan);
784             } catch (NumberFormatException e) {
785                 ci.println("Please enter Valid Vlan");
786                 return;
787             }
788         }
789
790         Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
791         configs.put(ConfigConstants.TYPE, "VLAN");
792         configs.put(ConfigConstants.VLAN, vlan);
793
794         Status status;
795         Node node = Node.fromString(nodeName);
796         if (node == null) {
797             ci.println("Invalid Node");
798             return;
799         }
800         status = this.addPort(node, bridgeName, portName, configs);
801         ci.println("Port creation status : "+status.toString());
802     }
803
804     public void _addTunnel (CommandInterpreter ci) {
805         String nodeName = ci.nextArgument();
806         if (nodeName == null) {
807             ci.println("Please enter Node Name");
808             return;
809         }
810
811         String bridgeName = ci.nextArgument();
812         if (bridgeName == null) {
813             ci.println("Please enter Bridge Name");
814             return;
815         }
816
817         String portName = ci.nextArgument();
818         if (portName == null) {
819             ci.println("Please enter Port Name");
820             return;
821         }
822
823         String tunnelType = ci.nextArgument();
824         if (tunnelType == null) {
825             ci.println("Please enter Tunnel Type");
826             return;
827         }
828
829         String remoteIp = ci.nextArgument();
830         if (remoteIp == null) {
831             ci.println("Please enter valid Remote IP Address");
832             return;
833         }
834
835         try {
836             InetAddress.getByName(remoteIp);
837         }  catch (Exception e) {
838             logger.error("Unable to resolve " + remoteIp, e);
839             ci.println("Please enter valid Remote IP Address");
840             return;
841         }
842
843         Map<ConfigConstants, Object> configs = new HashMap<ConfigConstants, Object>();
844         configs.put(ConfigConstants.TYPE, "TUNNEL");
845         configs.put(ConfigConstants.TUNNEL_TYPE, tunnelType);
846         configs.put(ConfigConstants.DEST_IP, remoteIp);
847
848         Status status;
849         Node node = Node.fromString(nodeName);
850         if (node == null) {
851             ci.println("Invalid Node");
852             return;
853         }
854         status = this.addPort(node, bridgeName, portName, configs);
855         ci.println("Port creation status : "+status.toString());
856     }
857
858     public void _printCache (CommandInterpreter ci) {
859         String nodeName = ci.nextArgument();
860         if (nodeName == null) {
861             ci.println("Please enter Node Name");
862             return;
863         }
864         Node node = Node.fromString(nodeName);
865         if (node == null) {
866             ci.println("Invalid Node");
867             return;
868         }
869         ovsdbInventoryService.printCache(node);
870     }
871
872     public void _forceConnect (CommandInterpreter ci) {
873         String force = ci.nextArgument();
874         if (force.equalsIgnoreCase("YES")) {
875             forceConnect = true;
876         }
877         else if (force.equalsIgnoreCase("NO")) {
878             forceConnect = false;
879         }
880         else {
881             ci.println("Please enter YES or NO.");
882         }
883         ci.println("Current ForceConnect State : "+forceConnect);
884     }
885
886     @Override
887     public String getHelp() {
888         StringBuilder help = new StringBuilder();
889         help.append("---OVSDB CLI---\n");
890         help.append("\t ovsconnect <ConnectionName> <ip-address>                        - Connect to OVSDB\n");
891         help.append("\t addBridge <Node> <BridgeName>                                   - Add Bridge\n");
892         help.append("\t getBridgeDomains <Node>                                         - Get Bridges\n");
893         help.append("\t deleteBridgeDomain <Node> <BridgeName>                          - Delete a Bridge\n");
894         help.append("\t addPort <Node> <BridgeName> <PortName> <type> <options pairs>   - Add Port\n");
895         help.append("\t deletePort <Node> <BridgeName> <PortName>                       - Delete Port\n");
896         help.append("\t addPortVlan <Node> <BridgeName> <PortName> <vlan>               - Add Port, Vlan\n");
897         help.append("\t addTunnel <Node> <Bridge> <Port> <tunnel-type> <remote-ip>      - Add Tunnel\n");
898         help.append("\t printCache <Node>                                               - Prints Table Cache");
899         return help.toString();
900     }
901
902
903     /**
904      * Add a new bridge
905      * @param node Node serving this configuration service
906      * @param bridgeIdentifier String representation of a Bridge Connector
907      * @return Bridge Connector configurations
908      */
909     @Override
910     @Deprecated
911     public Status createBridgeDomain(Node node, String bridgeIdentifier, Map<ConfigConstants, Object> configs) {
912         Connection connection = connectionService.getConnection(node);
913         OvsdbClient client = connection.getClient();
914         Bridge bridge = client.createTypedRowWrapper(Bridge.class);
915         bridge.setName(bridgeIdentifier);
916
917         String ovsTableUuid = this.getSpecialCaseParentUUID(node, OvsVswitchdSchemaConstants.DATABASE_NAME, bridge.getSchema().getName());
918         return this.insertRow(node, bridge.getSchema().getName(), ovsTableUuid, bridge.getRow());
919     }
920
921     /**
922      * Create a Port Attached to a Bridge
923      * Ex. ovs-vsctl add-port br0 vif0
924      * @param node Node serving this configuration service
925      * @param bridgeIdentifier String representation of a Bridge Domain
926      * @param portIdentifier String representation of a user defined Port Name
927      */
928     @Override
929     @Deprecated
930     public Status addPort(Node node, String bridgeIdentifier, String portIdentifier,
931                           Map<ConfigConstants, Object> configs) {
932         Connection connection = connectionService.getConnection(node);
933         OvsdbClient client = connection.getClient();
934
935         Bridge bridge = client.getTypedRowWrapper(Bridge.class, null);
936         ConcurrentMap<String, Row> rows = this.getRows(node, bridge.getSchema().getName());
937         if (rows == null || rows.size() == 0) {
938             return new Status(StatusCode.NOTFOUND);
939         }
940         for (String bridgeUuid : rows.keySet()) {
941             Row bridgeRow = rows.get(bridgeUuid);
942             bridge = client.getTypedRowWrapper(Bridge.class, bridgeRow);
943             if (bridge.getName().equals(bridgeIdentifier)) break;
944         }
945         if (bridge.getName() == null || !bridge.getName().equals(bridgeIdentifier)) {
946             return new Status(StatusCode.NOTFOUND);
947         }
948
949         Map<String, String> options = null;
950         String type = null;
951         Set<Long> tags = null;
952         if (configs != null) {
953             type = (String) configs.get(ConfigConstants.TYPE);
954             Map<String, String> customConfigs = (Map<String, String>) configs.get(ConfigConstants.CUSTOM);
955             if (customConfigs != null) {
956                 options = new HashMap<String, String>();
957                 for (String customConfig : customConfigs.keySet()) {
958                     options.put(customConfig, customConfigs.get(customConfig));
959                 }
960             }
961         }
962
963         if (type != null) {
964             logger.debug("Port type : " + type);
965             if (type.equalsIgnoreCase(OvsVswitchdSchemaConstants.PortType.VLAN.name())) {
966                 tags = new HashSet<Long>();
967                 tags.add(Long.parseLong((String)configs.get(ConfigConstants.VLAN)));
968             }
969         }
970
971         Port port = client.createTypedRowWrapper(Port.class);
972         port.setName(portIdentifier);
973         if (tags != null) port.setTag(tags);
974         StatusWithUuid portStatus = this.insertRow(node, port.getSchema().getName(), bridge.getUuid().toString(), port.getRow());
975
976         if (!portStatus.isSuccess()) return portStatus;
977         // Ugly hack by adding a sleep for the Monitor Update to catch up.
978         // TODO : Remove this once the Select operation is in place.
979         // We are currently relying on the local Cache for any GET operation and that might fail if we try to
980         // fetch the last installed entry. Hence we need the Select operation to work.
981
982         try {
983             Thread.sleep(2000);
984         } catch (InterruptedException e) {
985             // TODO Auto-generated catch block
986             e.printStackTrace();
987         }
988
989         Interface interfaceRow = client.createTypedRowWrapper(Interface.class);
990         ConcurrentMap<String, Row> intfRows = this.getRows(node, interfaceRow.getSchema().getName());
991         if (intfRows == null || intfRows.size() == 0) {
992             return new Status(StatusCode.NOTFOUND);
993         }
994         for (String intfUuid : intfRows.keySet()) {
995             Row intfRow = rows.get(intfUuid);
996             interfaceRow = client.getTypedRowWrapper(Interface.class, intfRow);
997             if (interfaceRow == null || interfaceRow.getName() == null) continue;
998             if (interfaceRow.getName().equals(portIdentifier)) break;
999         }
1000         if (interfaceRow.getName() == null || !interfaceRow.getName().equals(portIdentifier)) {
1001             return new Status(StatusCode.NOTFOUND);
1002         }
1003
1004         if (type != null) {
1005             logger.debug("Interface type : " + type);
1006             if (type.equalsIgnoreCase(OvsVswitchdSchemaConstants.PortType.TUNNEL.name())) {
1007                 interfaceRow.setType((String)configs.get(ConfigConstants.TUNNEL_TYPE));
1008                 if (options == null) options = new HashMap<String, String>();
1009                 options.put("remote_ip", (String)configs.get(ConfigConstants.DEST_IP));
1010             } else if (type.equalsIgnoreCase(OvsVswitchdSchemaConstants.PortType.PATCH.name()) ||
1011                        type.equalsIgnoreCase(OvsVswitchdSchemaConstants.PortType.INTERNAL.name())) {
1012                 interfaceRow.setType(type.toLowerCase());
1013             }
1014         }
1015         if (options != null) {
1016             interfaceRow.setOptions(options);
1017         }
1018
1019         Status intfStatus = null;
1020         intfStatus = this.updateRow(node, interfaceRow.getSchema().getName(), portStatus.getUuid().toString(),
1021                                     interfaceRow.getUuid().toString(), interfaceRow.getRow());
1022
1023         if (intfStatus.isSuccess()) return portStatus;
1024         return intfStatus;
1025     }
1026
1027     /**
1028      * Implements the OVS Connection for Managers
1029      *
1030      * @param node Node serving this configuration service
1031      * @param managerip String Representing IP and connection types
1032      */
1033     @SuppressWarnings("unchecked")
1034     @Deprecated
1035     public boolean setManager(Node node, String managerip) {
1036         Connection connection = connectionService.getConnection(node);
1037         OvsdbClient client = connection.getClient();
1038         Manager manager = client.createTypedRowWrapper(Manager.class);
1039         manager.setTarget(ImmutableSet.of(managerip));
1040
1041         OpenVSwitch openVSwitch = connection.getClient().getTypedRowWrapper(OpenVSwitch.class, null);
1042         ConcurrentMap<String, Row> row = this.getRows(node, openVSwitch.getSchema().getName());
1043         if (row == null || row.size() == 0) {
1044             return false;
1045         }
1046         String ovsTableUuid = (String)row.keySet().toArray()[0];
1047
1048         Status status = this.insertRow(node, manager.getSchema().getName(), ovsTableUuid, manager.getRow());
1049         return status.isSuccess();
1050     }
1051
1052     @Override
1053     @Deprecated
1054     public Status addBridgeDomainConfig(Node node, String bridgeIdentfier,
1055             Map<ConfigConstants, Object> configs) {
1056         String mgmt = (String)configs.get(ConfigConstants.MGMT);
1057         if (mgmt != null) {
1058             if (setManager(node, mgmt)) return new Status(StatusCode.SUCCESS);
1059         }
1060         return new Status(StatusCode.BADREQUEST);
1061     }
1062
1063     @Override
1064     @Deprecated
1065     public Status deletePort(Node node, String bridgeIdentifier, String portIdentifier) {
1066         Connection connection = connectionService.getConnection(node);
1067         OvsdbClient client = connection.getClient();
1068
1069         Port port = client.getTypedRowWrapper(Port.class, null);
1070         ConcurrentMap<String, Row> rows = this.getRows(node, port.getSchema().getName());
1071         if (rows == null || rows.size() == 0) {
1072             return new Status(StatusCode.NOTFOUND);
1073         }
1074         for (String portUuid : rows.keySet()) {
1075             Row bridgeRow = rows.get(portUuid);
1076             port = client.getTypedRowWrapper(Port.class, bridgeRow);
1077             if (port.getName().equals(portIdentifier)) break;
1078         }
1079         if (port.getName() == null || !port.getName().equals(portIdentifier)) {
1080             return new Status(StatusCode.NOTFOUND);
1081         }
1082         return this.deleteRow(node, port.getSchema().getName(), port.getUuid().toString());
1083     }
1084
1085     @Override
1086     @Deprecated
1087     public Status deleteBridgeDomain(Node node, String bridgeIdentifier) {
1088         Connection connection = connectionService.getConnection(node);
1089         OvsdbClient client = connection.getClient();
1090
1091         Bridge bridge = client.getTypedRowWrapper(Bridge.class, null);
1092         ConcurrentMap<String, Row> rows = this.getRows(node, bridge.getSchema().getName());
1093         if (rows == null || rows.size() == 0) {
1094             return new Status(StatusCode.NOTFOUND);
1095         }
1096         for (String bridgeUuid : rows.keySet()) {
1097             Row bridgeRow = rows.get(bridgeUuid);
1098             bridge = client.getTypedRowWrapper(Bridge.class, bridgeRow);
1099             if (bridge.getName().equals(bridgeIdentifier)) break;
1100         }
1101         if (bridge.getName() == null || !bridge.getName().equals(bridgeIdentifier)) {
1102             return new Status(StatusCode.NOTFOUND);
1103         }
1104         return this.deleteRow(node, bridge.getSchema().getName(), bridge.getUuid().toString());
1105     }
1106
1107     @Override
1108     public List<String> getBridgeDomains(Node node) {
1109         if (connectionService == null) {
1110             logger.error("Couldn't refer to the ConnectionService");
1111             return null;
1112         }
1113
1114         Connection connection = connectionService.getConnection(node);
1115         Bridge bridge = connection.getClient().getTypedRowWrapper(Bridge.class, null);
1116         List<String> brlist = new ArrayList<String>();
1117         Map<String, Row> brTableCache = ovsdbInventoryService.getTableCache(node, OvsVswitchdSchemaConstants.DATABASE_NAME, bridge.getSchema().getName());
1118         if(brTableCache != null){
1119             for (String uuid : brTableCache.keySet()) {
1120                 bridge = connection.getClient().getTypedRowWrapper(Bridge.class, brTableCache.get(uuid));
1121                 brlist.add(bridge.getName());
1122             }
1123         }
1124         return brlist;
1125     }
1126
1127     @Override
1128     public NodeConnector getNodeConnector(Node arg0, String arg1, String arg2) {
1129         return null;
1130     }
1131
1132     @Override
1133     @Deprecated
1134     public Status addPortConfig(Node node, String bridgeIdentifier, String portIdentifier,
1135             Map<ConfigConstants, Object> configs) {
1136         // TODO Auto-generated method stub
1137         return null;
1138     }
1139
1140     @Override
1141     @Deprecated
1142     public Node getBridgeDomainNode(Node node, String bridgeIdentifier) {
1143         // TODO Auto-generated method stub
1144         return null;
1145     }
1146
1147     @Override
1148     @Deprecated
1149     public Map<ConfigConstants, Object> getPortConfigs(Node node, String bridgeIdentifier,
1150             String portIdentifier) {
1151         // TODO Auto-generated method stub
1152         return null;
1153     }
1154
1155     @Override
1156     @Deprecated
1157     public Status removeBridgeDomainConfig(Node node, String bridgeIdentifier,
1158             Map<ConfigConstants, Object> configs) {
1159         // TODO Auto-generated method stub
1160         return null;
1161     }
1162
1163     @Override
1164     @Deprecated
1165     public Status removePortConfig(Node node, String bridgeIdentifier, String portIdentifier,
1166             Map<ConfigConstants, Object> configs) {
1167         // TODO Auto-generated method stub
1168         return null;
1169     }
1170
1171     @Override
1172     @Deprecated
1173     public Map<ConfigConstants, Object> getBridgeDomainConfigs(Node node, String bridgeIdentifier) {
1174         // TODO Auto-generated method stub
1175         return null;
1176     }
1177
1178     @Override
1179     public UUID insertRow(Node node, String databaseName, String tableName, String parentTable, UUID parentUuid,
1180                           String parentColumn, Row<GenericTableSchema> row) throws OvsdbPluginException {
1181         throw new OvsdbPluginException("Not implemented Yet");
1182     }
1183
1184     @Override
1185     public UUID insertRow(Node node, String databaseName, String tableName,
1186             UUID parentRowUuid, Row<GenericTableSchema> row)
1187             throws OvsdbPluginException {
1188         throw new OvsdbPluginException("Not implemented Yet");
1189     }
1190
1191     @Override
1192     public Row<GenericTableSchema> insertTree(Node node, String databaseName, String tableName, String parentTable, UUID parentRowUuid,
1193                                               String parentColumn, Row<GenericTableSchema> row) throws OvsdbPluginException {
1194         throw new OvsdbPluginException("Not implemented Yet");
1195     }
1196
1197     @Override
1198     public Row<GenericTableSchema> insertTree(Node node, String databaseName,
1199             String tableName, UUID parentRowUuid, Row<GenericTableSchema> row)
1200             throws OvsdbPluginException {
1201         throw new OvsdbPluginException("Not implemented Yet");
1202     }
1203
1204     @Override
1205     public Row<GenericTableSchema> updateRow(Node node, String databaseName,
1206             String tableName, UUID rowUuid, Row<GenericTableSchema> row,
1207             boolean overwrite) throws OvsdbPluginException {
1208         throw new OvsdbPluginException("Not implemented Yet");
1209     }
1210
1211     @Override
1212     public void deleteRow(Node node, String databaseName, String tableName, String parentTable, UUID parentRowUuid,
1213             String parentColumn, UUID rowUuid) throws OvsdbPluginException {
1214         throw new OvsdbPluginException("Not implemented Yet");
1215     }
1216
1217     @Override
1218     public void deleteRow(Node node, String databaseName, String tableName,
1219             UUID rowUuid) throws OvsdbPluginException {
1220         throw new OvsdbPluginException("Not implemented Yet");
1221     }
1222
1223     @Override
1224     public Row<GenericTableSchema> getRow(Node node, String databaseName,
1225             String tableName, UUID uuid) throws OvsdbPluginException {
1226         throw new OvsdbPluginException("Not implemented Yet");
1227     }
1228
1229     @Override
1230     public ConcurrentMap<UUID, Row<GenericTableSchema>> getRows(Node node,
1231             String databaseName, String tableName) throws OvsdbPluginException {
1232         throw new OvsdbPluginException("Not implemented Yet");
1233     }
1234
1235     @Override
1236     public ConcurrentMap<UUID, Row<GenericTableSchema>> getRows(Node node,
1237             String databaseName, String tableName, String fiqlQuery)
1238             throws OvsdbPluginException {
1239         throw new OvsdbPluginException("Not implemented Yet");
1240     }
1241
1242     @Override
1243     public List<String> getTables(Node node, String databaseName) throws OvsdbPluginException {
1244         throw new OvsdbPluginException("Not implemented Yet");
1245     }
1246 }
1247