User Guide - vmware-archive/ovsdb-client-library GitHub Wiki

Table of Contents

Interfaces

Three most important interfaces are: OvsdbActiveConnectionConnector, OvsdbPassiveConnectionListener and OvsdbClient.

OvsdbActiveConnectionConnector

This interface can be used to actively connect to an OVSDB server. And the OVSDB server should passively listen on a port (typically 6640) for the connections.

Get an Instance

This interface contains two methods: connect() and connectWithSsl(). This interface has one implementation: OvsdbActiveConnectionConnectorImpl. Its constructor takes an ScheduledExecutorService for asynchronous operations. To construct a OvsdbActiveConnectionConnector:

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); 
OvsdbActiveConnectionConnector connector = new OvsdbActiveConnectionConnectorImpl(executorService);

Connect

CompletableFuture<OvsdbClient> connect(String ip, int port);

connect() method takes an IP address and a port. It returns a CompletableFuture of OvsdbClient. This call establishes a TCP connection to an OVSDB server on specified ip:port. It may only be used in testing but not production. An OvsdbClient can be retrieved from the returned CompletableFuture once the connection is established:

OvsdbClient ovsdbClient = connector.connect("192.168.11.2", 6640).join();

Connect With SSL

CompletableFuture<OvsdbClient> connectWithSsl(String ip, int port, SslContext sslContext);

This method is similar to connect() but instead of establishing a TCP connection, it establishes a SSL connection with the OVSDB server. Thus, it takes one more parameter - an SslContext object. Example of using a self-signed certificates for the SslContext:

SelfSignedCertificate serverCaCert = new SelfSignedCertificate();  // CA certificate that signs OVSDB server's certifcate
SelfSignedCertificate clientCert = new SelfSignedCertificate();    // Certificate for OVSDB clienet
SslContext sslContext = SslContextBuilder.forClient()
    .keyManager(clientCert.key(), clientCert.cert())               // Client's private key and certificate
    .trustManager(serverCaCert.cert())                             // The client trusts the server's CA cert
    .build();
OvsdbClient ovsdbClient = connector.connectWithSsl("192.168.11.2", 6640, sslContext).join();

This is just a demonstration of constructing an SslContext. In reality, the serverCaCert should be the CA cert that signs the OVSDB server's certificate and the clientCert should be the OVSBD client's certificate, which may also be signed by a CA.

OvsdbPassiveConnectionListener

This interface can be used to passively listening on a port (typically 6640) for connection from an OVSDB server. And the OVSDB server should actively connection to the port.

Get an Instance

This interface contains three methods: startListening(), startListeningWithSsl() and stopListening(). This interface has one implementation: OvsdbPassiveConnectionListenerImpl. Its constructor takes an ScheduledExecutorService for asynchronous operations. To construct a OvsdbPassiveConnectionListener:

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); 
OvsdbPassiveConnectionListener listener = new OvsdbPassiveConnectionListenerImpl(executorService);

Start Listening

CompletableFuture<Boolean> startListening(int port, ConnectionCallback connectionCallback);

startListening() method takes a port and a ConnectionCallback, which will be notified when a new OVSDB server is connected or when a connected OVSDB server is now disconnected. It returns a CompletableFuture of Boolean, which indicates whether this listening is started successfully or not. This call listens for TCP connections from OVSDB servers. It may only be used in testing but not production. An OvsdbClient can be retrieved from the connected() method in the callback:

ConnectionCallback connectionCallback = new ConnectionCallback() {      // (2)
    public void connected(OvsdbClient ovsdbClient) {
        //...
    }
    public void disconnected(OvsdbClient ovsdbClient) {
        //...
    }
};
listener.startListening(6640, connectionCallback).join();       // (3)

Start Listening with SSL

CompletableFuture<Boolean> startListeningWithSsl(
    int port, SslContext sslContext, ConnectionCallback connectionCallback
);

This method is similar to startListening() but instead of listening for TCP connections, it listens for SSL connections from OVSDB servers. Thus, it takes one more parameter - an SslContext object. Example of using a self-signed certificates for the SslContext:

SelfSignedCertificate serverCert = new SelfSignedCertificate();    // The controller's certificate
SelfSignedCertificate clientCaCert = new SelfSignedCertificate();  // CA certificate that signs OVSDB server's certifcate
SslContext sslContext = SslContextBuilder
    .forServer(serverCert.certificate(), serverCert.privateKey())  // Controller's certificate and private key
    .trustManager(clientCaCert.certificate())                      // Trust the OVSDB servers' CA cert
    .build();
listener.startListeningWithSsl(6640, connectionCallback, sslContext).join();

This is just a demonstration of constructing an SslContext. In reality, the clientCaCert should be the CA cert that signs all the OVSDB servers' certificate and the serverCert should be the controller's certificate, which may also be signed by a CA.

Note: Don't confuse the "client" and "server" here. From the SSL point of view, since the controller listens for connections from OVSDB servers, it is a "server" and an OVSDB server which connects to the listener is a "client".

Stop Listening

CompletableFuture<Boolean> stopListening(int port);

stopListening() method stops the listening on the given port. It returns a CompletableFuture of Boolean, which indicates whether it successfully stops the listening or not.

OvsdbClient

An OvsdbClient object is what you can use to configure an OVSDB server. Thus, the interface contains all RPC methods defined in RFC 7047 Section 4.1 RPC Methods. All methods are asynchronous and return a CompletableFuture of the result. And they will throw an OvsdbClientException if it fails to get the result. There is a configuration timeout for each RPC request. If the response from the OVSDB server doesn't come within the timeout value, the CompletableFuture will complete exceptionally with a TimeoutException. For how to configure the timeout value, see Configuration section below.

List Databases

CompletableFuture<String[]> listDatabases() throws OvsdbClientException;

See RFC 7047 Section 4.1.1 List Databases

Get Schema

CompletableFuture<DatabaseSchema> getSchema(String dbName) throws OvsdbClientException;

See RFC 7047 Section 4.1.2 Get Schema. It takes a database name and the result is a DatabaseSchema, which is a Java representation of <database-schema>.

Transact

CompletableFuture<OperationResult[]> transact(
    String dbName, List<Operation> operations
) throws OvsdbClientException;

See RFC 7047 Section 4.1.3 Transact

This method takes a database name ad a list of operations in this transaction. Operation is an abstract class and has the following subclasses: Insert, Select, Update, Mutate, Delete, Wait, Commit, Abort, Comment and Assert.

The transact method returns a List of OperationResult, corresponding to the List of Operation parameter. OperationResult is an abstract class and has the following implementations: InsertResult, SelectResult, UpdateResult, EmptyResult and ErrorResult.

Insert

See RFC 7047 Section 5.2.1 Insert. Because the "uuid-name" field is optional, the Insert class has two constructors:

public Insert(String table, Row row)
public Insert(String table, Row row, String uuidName)

But the user can still add a uuid-name with the first constructor. In other words, the following two statements have the same effect:

new Insert(table, row, uuidName);
new Insert(table, row).withUuidName(uuidName);

A Row is a Java representation of <row>. The constructor takes no parameters because this class provides builder-style setters for columns in the row. For example:

Row row = new Row()
    .stringColumn("name", "ls1")
    .integerColumn("tunnel_key", 5000);

The result of a Insert operation can either be a InsertResult, which contains the UUID of the inserted row; or an ErrorResult, which contains the error and details.

Select

See RFC 7047 Section 5.2.2 Select. Select has three constructors:

public Select(String table)
public Select(String table, List<Condition> where)
public Select(String table, List<Condition> where, List<String> columns)

Builder-style setters are provided. For example:

Select select = new Select("Logical_Switch")
    .where("name", Function.EQUALS, "ls1")
    .columns("name", "description", "tunnel_key");

The user can also provide a List of Condition (where) and a List of String (columns) while constructing the Select object.

The result of an Insert operation is a SelectResult, which contains a list of selected rows.

Update

See RFC 7047 Section 5.2.3 Update. Update has two constructors:

public Update(String table, List<Condition> where, Row row)
public Update(String table, Row row)

To construct an Update object:

Update update = new Update("Logical_Switch", row)
    .where("name", Function.EQUALS, "ls1");

Or pass a List of Condition to the constructor.

The result of an Update operation can either be a UpdateResult, which contains the count of the rows updated; or an ErrorResult, which contains the error and details.

Mutate

See RFC 7047 Section 5.2.4 Mutate. Mutate has two constructors:

public Mutate(String table)
public Mutate(String table, List<Condition> where, List<Mutation> mutations)

To construct a Mutate object:

Mutate update = new Mutate("Logical_Switch")
    .where("name", Function.EQUALS, "ls1")
    .mutation("tunnel_key", Mutator.SUM, 1);

Or pass a List of Condition and a List of Mutation to the constructor.

The result of a Mutate operation can either be a UpdateResult, which contains the count of the rows mutated; or an ErrorResult, which contains the error and details.

Delete

See RFC 7047 Section 5.2.5 Delete. Delete has two constructors:

public Delete(String table)
public Delete(String table, List<Condition> where)

To construct a Delete object:

Delete delete = new Delete("Logical_Switch")
    .where("name", Function.EQUALS, "ls1")

Or pass a List of Condition to the constructor.

The result of a Delete operation can either be a UpdateResult, which contains the count of the rows deleted; or an ErrorResult, which contains the error and details.

Wait

See RFC 7047 Section 5.2.6 Wait. Wait has two constructors:

public Wait(
    String table, List<Condition> where,
    List<String> columns, Until until, List<Row> rows
)
public Wait(
    String table, Integer timeout, List<Condition> where,
    List<String> columns, Until until, List<Row> rows
)

The result of a `Wait` operation can either be an `EmptyResult`, which is empty; or an `ErrorResult`, which contains the error and details.

#### Commit
See [RFC 7047 Section 5.2.7 Commit](https://tools.ietf.org/html/rfc7047#section-5.2.7). `Commit` has one constructor:
```java
public Commit(boolean durable)

The result of a Commit operation can either be an EmptyResult, which is empty; or an ErrorResult, which contains the error and details.

Abort

See RFC 7047 Section 5.2.8 Abort. Abort has one constructor:

public Abort()

The result of an Abort operation can either be an EmptyResult, which is empty; or an ErrorResult, which contains the error and details.

Comment

See RFC 7047 Section 5.2.9 Comment. Comment has one constructor:

public Comment(String comment)

The result of an Comment operation is an EmptyResult, which is empty.

Assert

See RFC 7047 Section 5.2.10 Assert. Assert has one constructor:

public Assert(String lock)

The result of a Assert## operation can either be an EmptyResult, which is empty; or an ErrorResult, which contains the error and details.

Monitor

CompletableFuture<TableUpdates> monitor(
      String dbName, String monitorId, MonitorRequests monitorRequests,
      MonitorCallback monitorCallback
) throws OvsdbClientException;

See RFC 7047 Section 4.1.5 Monitor.

The method takes a database name, a unique monitor id, a MonitorRequests and a MonitorCallback. The MonitorCallback interface has only one method void update(TableUpdates tableUpdates); , which will be called when a TableUpdates of this monitor comes from the OVSDB server. The result is a CompletableFuture that can be used to retrieve the initial TableUpdates.

Monitor Cancellation

CompletableFuture<Void> cancelMonitor(String monitorId) throws OvsdbClientException;

See RFC 7047 Section 4.1.7 Monitor Cancellation.

cancelMonitor() method takes a monitorId that was ever passed to a monitor() method.

Lock

CompletableFuture<LockResult> lock(
    String lockId, LockCallback lockCallback
) throws OvsdbClientException;

See RFC 7047 Section 4.1.7 Lock Operations.

lock() method takes a unique lock id and a LockCallback, which will be notified when the lock is locked or is stolen.

This method returns a CompletableFuture which can be used to retrieve the LockResult.

Steal

CompletableFuture<LockResult> steal(
    String lockId, LockCallback lockCallback
) throws OvsdbClientException;

See RFC 7047 Section 4.1.7 Lock Operations.

steal() method takes a unique lock id and a LockCallback, which will be notified when the lock is again stolen by others.

Unlock

CompletableFuture<Void> unlock(String lockId) throws OvsdbClientException;

See RFC 7047 Section 4.1.7 Lock Operations.

unlock() method takes a unique lock id.

Get Connection Info

OvsdbConnectionInfo getConnectionInfo();

getConnectionInfo() method can be used to get the connection information between the OVSDB client and the OVSDB server. OvsdbConnectionInfo contains the following information: local address, local port, remote address, remote port, local certificate and remote certificate.

Shutdown

void shutdown();

shutdown() method can be used to shutdown the OvsdbClient. It will disconnect the OVSDB client from the OVSDB server. After shutdown() is called, this OvsdbClient can not be reused.'

Example

You may checkout the tests for more examples.

Configurations

All the configurable parameters are put in the ovsdb-client.properties file. All properties have a default value so that the user doesn't have to set them. The properties include:

Channel Read Idle Timeout

Property name: channel.read.idle.timeout.sec.
Default value: 30.

If during that many seconds, there is no traffic from the OVSDB server, we an channel read idle event will be raised internally, after which an echo message will be sent to the OVSDB server. This property can be used together with channel.read.idle.max.

Channel Read Idle Max Limit

Property name: channel.read.idle.max.
Default value: 3.

If the channel read idle event has been raised for more than this limit (continuously), the connection to the OVSDB server will be cut. It can be used together with channel-read-idle-timeout.

RPC Request Timeout

Property name: rpc.timeout.sec
Default value: 60.

This property means how many seconds do we wait for a response from the OVSDB server before completing the future with a TimeoutException.

Example

The following is an example of an ovsdb-client.properties file.

channel.read.idle.timeout.sec=10
channel.read.idle.max=5
rpc.timeout.sec=30
⚠️ **GitHub.com Fallback** ⚠️