com.vmware.ovsdb.service.impl.OvsdbClientImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2018 VMware, Inc. All Rights Reserved.
*
* This product is licensed to you under the BSD-2 license (the "License").
* You may not use this product except in compliance with the BSD-2 License.
*
* This product may include a number of subcomponents with separate copyright
* notices and license terms. Your use of these subcomponents is subject to the
* terms and conditions of the subcomponent's license, as noted in the LICENSE
* file.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
package com.vmware.ovsdb.service.impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.vmware.ovsdb.callback.LockCallback;
import com.vmware.ovsdb.callback.MonitorCallback;
import com.vmware.ovsdb.exception.OvsdbClientException;
import com.vmware.ovsdb.jsonrpc.v1.annotation.JsonRpcServiceMethod;
import com.vmware.ovsdb.jsonrpc.v1.exception.JsonRpcException;
import com.vmware.ovsdb.jsonrpc.v1.exception.JsonRpcTransportException;
import com.vmware.ovsdb.jsonrpc.v1.service.JsonRpcV1Client;
import com.vmware.ovsdb.jsonrpc.v1.service.JsonRpcV1Server;
import com.vmware.ovsdb.jsonrpc.v1.service.impl.JsonRpcV1ClientImpl;
import com.vmware.ovsdb.jsonrpc.v1.service.impl.JsonRpcV1ServerImpl;
import com.vmware.ovsdb.jsonrpc.v1.spi.JsonRpcTransporter;
import com.vmware.ovsdb.jsonrpc.v1.util.JsonUtil;
import com.vmware.ovsdb.netty.JsonRpcHandler;
import com.vmware.ovsdb.protocol.methods.LockResult;
import com.vmware.ovsdb.protocol.methods.MonitorRequests;
import com.vmware.ovsdb.protocol.methods.TableUpdates;
import com.vmware.ovsdb.protocol.operation.Operation;
import com.vmware.ovsdb.protocol.operation.result.OperationResult;
import com.vmware.ovsdb.protocol.schema.DatabaseSchema;
import com.vmware.ovsdb.protocol.util.OvsdbConstant;
import com.vmware.ovsdb.service.OvsdbClient;
import com.vmware.ovsdb.service.OvsdbConnectionInfo;
import com.vmware.ovsdb.util.PropertyManager;
import io.netty.channel.Channel;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
public class OvsdbClientImpl implements OvsdbClient {
private static long RPC_TIMEOUT_SEC = PropertyManager.getLongProperty("rpc.timeout.sec", 60);
private static final AtomicLong callId = new AtomicLong(0);
private final OvsdbConnectionInfo connectionInfo;
private final JsonRpcV1Client jsonRpcClient;
private final JsonRpcV1Server jsonRpcServer;
private final ConcurrentMap monitorCallbacks = new ConcurrentHashMap<>();
private final ConcurrentMap lockCallbacks = new ConcurrentHashMap<>();
private final AtomicBoolean isActive = new AtomicBoolean(true);
/**
* Create an {@link OvsdbClient} instance from a Netty channel.
*
* @param executorService used for asynchronous operations
* @param channel a Netty {@link Channel} object
*/
public OvsdbClientImpl(ScheduledExecutorService executorService, Channel channel) {
this.connectionInfo = OvsdbConnectionInfo.fromChannel(channel);
JsonRpcTransporter transporter = new JsonRpcTransporter() {
@Override
public void send(JsonNode data) throws JsonRpcTransportException {
try {
channel.writeAndFlush(JsonUtil.serialize(data));
} catch (Throwable ex) {
throw new JsonRpcTransportException(ex);
}
}
@Override
public void close() {
channel.close();
}
};
jsonRpcClient = new JsonRpcV1ClientImpl(
transporter, executorService, RPC_TIMEOUT_SEC, TimeUnit.SECONDS);
jsonRpcServer = new JsonRpcV1ServerImpl(transporter, new OvsdbRequestHandler());
channel.pipeline().addAfter("ovsdbConnectionHandler", "jsonRpcHandler",
new JsonRpcHandler(jsonRpcClient, jsonRpcServer, executorService));
}
@Override
public CompletableFuture listDatabases() throws OvsdbClientException {
return callMethod(OvsdbConstant.LIST_DBS, String[].class);
}
@Override
public CompletableFuture getSchema(String dbName)
throws OvsdbClientException {
return callMethod(OvsdbConstant.GET_SCHEMA, DatabaseSchema.class, dbName);
}
@Override
public CompletableFuture transact(
String dbName, List operations
) throws OvsdbClientException {
Object[] params = new Object[operations.size() + 1];
params[0] = dbName;
for (int i = 0; i < operations.size(); i++) {
params[i + 1] = operations.get(i);
}
return callMethod(OvsdbConstant.TRANSACT, OperationResult[].class, params);
}
@Override
public CompletableFuture monitor(
String dbName, String monitorId, MonitorRequests monitorRequests,
MonitorCallback monitorCallback
) throws OvsdbClientException {
CompletableFuture completableFuture = callMethod(
OvsdbConstant.MONITOR, TableUpdates.class, dbName, monitorId, monitorRequests
);
// If this monitor request succeeds, save the callback
return completableFuture.thenApply(tableUpdates -> {
monitorCallbacks.put(monitorId, monitorCallback);
return tableUpdates;
});
}
@Override
public CompletableFuture cancelMonitor(String monitorId) throws OvsdbClientException {
CompletableFuture completableFuture = callMethod(
OvsdbConstant.MONITOR_CANCEL, Void.class, monitorId);
return completableFuture.thenApply(result -> {
monitorCallbacks.remove(monitorId);
return result;
});
}
@Override
public CompletableFuture lock(String lockId, LockCallback lockCallback)
throws OvsdbClientException {
return callMethod(OvsdbConstant.LOCK, LockResult.class, lockId)
.thenApply(lockResult -> {
lockCallbacks.put(lockId, lockCallback);
return lockResult;
});
}
@Override
public CompletableFuture steal(String lockId, LockCallback lockCallback)
throws OvsdbClientException {
return callMethod(OvsdbConstant.STEAL, LockResult.class, lockId)
.thenApply(lockResult -> {
lockCallbacks.put(lockId, lockCallback);
return lockResult;
});
}
@Override
public CompletableFuture unlock(String lockId) throws OvsdbClientException {
CompletableFuture completableFuture = callMethod(
OvsdbConstant.UNLOCK, Void.class, lockId);
return completableFuture.thenApply(result -> {
lockCallbacks.remove(lockId);
return result;
});
}
@Override
public OvsdbConnectionInfo getConnectionInfo() {
return connectionInfo;
}
@Override
public void shutdown() {
if (isActive.getAndSet(false)) {
jsonRpcClient.shutdown();
jsonRpcServer.shutdown();
monitorCallbacks.clear();
lockCallbacks.clear();
}
}
private String getNextId() {
return String.valueOf(callId.getAndIncrement());
}
private CompletableFuture callMethod(
String method, Class returnType, Object... params
) throws OvsdbClientException {
exceptionIfNotActive();
try {
return jsonRpcClient.call(getNextId(), method, returnType, params);
} catch (JsonRpcException ex) {
throw new OvsdbClientException(ex);
}
}
private void exceptionIfNotActive() throws OvsdbClientException {
if (!isActive.get()) {
throw new OvsdbClientException("This OVSDB client is not active");
}
}
public class OvsdbRequestHandler {
/**
* Handle "echo" request.
*
* @param params params of the echo request
*/
@JsonRpcServiceMethod(value = OvsdbConstant.ECHO)
public Object[] handleEcho(Object... params) {
return params;
}
/**
* Handle "update" notification.
*
* @param monitorId monitor id of this update
* @param tableUpdates table updates
*/
@JsonRpcServiceMethod(value = OvsdbConstant.UPDATE)
public void handleUpdate(String monitorId, TableUpdates tableUpdates) {
MonitorCallback monitorCallback = monitorCallbacks.get(monitorId);
if (monitorCallback != null) {
monitorCallback.update(tableUpdates);
}
}
/**
* Handle "locked" notification.
*
* @param lockId id of the lock that is locked
*/
@JsonRpcServiceMethod(value = OvsdbConstant.LOCKED)
public void handleLocked(String lockId) {
LockCallback lockCallback = lockCallbacks.get(lockId);
if (lockCallback != null) {
lockCallback.locked();
}
}
/**
* Handle "stolen" notification.
*
* @param lockId id of the lock that is stolen
*/
@JsonRpcServiceMethod(value = OvsdbConstant.STOLEN)
public void handleStolen(String lockId) {
LockCallback lockCallback = lockCallbacks.get(lockId);
if (lockCallback != null) {
lockCallback.stolen();
}
}
}
@Override
public String toString() {
return getClass().getSimpleName() + " ["
+ "connectionInfo=" + connectionInfo
+ ", isActive=" + isActive
+ "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy