66ea26b1bc
Splits jvpp into two jars jvpp-registry.jar - base jvpp functionality jvpp-core.jar - Java wrapper for vpe.api Plugins can be generated the same way jvpp-core.jar is. Example (nsh): https://gerrit.fd.io/r/#/c/2118/ Change-Id: I2254f90b2c3e423563bb91bf70877979f1e90a7d Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
138 lines
4.2 KiB
Java
138 lines
4.2 KiB
Java
/*
|
|
* Copyright (c) 2016 Cisco and/or its affiliates.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package org.openvpp.jvpp;
|
|
|
|
import static org.openvpp.jvpp.NativeLibraryLoader.loadLibrary;
|
|
|
|
import java.io.IOException;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
/**
|
|
* JNI based representation of a management connection to VPP.
|
|
*/
|
|
public final class VppJNIConnection implements VppConnection {
|
|
private static final Logger LOG = Logger.getLogger(VppJNIConnection.class.getName());
|
|
|
|
static {
|
|
final String libName = "libjvpp_registry.so.0.0.0";
|
|
try {
|
|
loadLibrary(libName, VppJNIConnection.class);
|
|
} catch (IOException e) {
|
|
LOG.log(Level.SEVERE, String.format("Can't find vpp jni library: %s", libName), e);
|
|
throw new ExceptionInInitializerError(e);
|
|
}
|
|
}
|
|
|
|
private ConnectionInfo connectionInfo;
|
|
|
|
private final String clientName;
|
|
private volatile boolean disconnected = false;
|
|
|
|
/**
|
|
* Create VPPJNIConnection instance for client connecting to VPP.
|
|
*
|
|
* @param clientName client name instance to be used for communication. Single connection per clientName is
|
|
* allowed.
|
|
*/
|
|
public VppJNIConnection(final String clientName) {
|
|
this.clientName = Objects.requireNonNull(clientName, "Null clientName");
|
|
}
|
|
|
|
/**
|
|
* Guarded by VppJNIConnection.class
|
|
*/
|
|
private static final Map<String, VppJNIConnection> connections = new HashMap<>();
|
|
|
|
/**
|
|
* Initiate VPP connection for current instance
|
|
*
|
|
* Multiple instances are allowed since this class is not a singleton (VPP allows multiple management connections).
|
|
*
|
|
* However only a single connection per clientName is allowed.
|
|
*
|
|
* @throws IOException in case the connection could not be established
|
|
*/
|
|
|
|
@Override
|
|
public void connect() throws IOException {
|
|
_connect();
|
|
}
|
|
|
|
private void _connect() throws IOException {
|
|
synchronized (VppJNIConnection.class) {
|
|
if (connections.containsKey(clientName)) {
|
|
throw new IOException("Client " + clientName + " already connected");
|
|
}
|
|
|
|
connectionInfo = clientConnect(clientName);
|
|
if (connectionInfo.status != 0) {
|
|
throw new IOException("Connection returned error " + connectionInfo.status);
|
|
}
|
|
connections.put(clientName, this);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public final void checkActive() {
|
|
if (disconnected) {
|
|
throw new IllegalStateException("Disconnected client " + clientName);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public final synchronized void close() {
|
|
if (!disconnected) {
|
|
disconnected = true;
|
|
try {
|
|
clientDisconnect();
|
|
} finally {
|
|
synchronized (VppJNIConnection.class) {
|
|
connections.remove(clientName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public ConnectionInfo getConnectionInfo() {
|
|
return connectionInfo;
|
|
}
|
|
|
|
/**
|
|
* VPP connection information used by plugins to reuse the connection.
|
|
*/
|
|
public static final class ConnectionInfo {
|
|
public final long queueAddress;
|
|
public final int clientIndex;
|
|
public final int status; // FIXME throw exception instead
|
|
|
|
public ConnectionInfo(long queueAddress, int clientIndex, int status) {
|
|
this.queueAddress = queueAddress;
|
|
this.clientIndex = clientIndex;
|
|
this.status = status;
|
|
}
|
|
}
|
|
|
|
private static native ConnectionInfo clientConnect(String clientName);
|
|
|
|
private static native void clientDisconnect();
|
|
|
|
}
|