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>
134 lines
4.7 KiB
Java
134 lines
4.7 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 java.util.Objects.requireNonNull;
|
|
|
|
import java.io.IOException;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.ConcurrentMap;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import org.openvpp.jvpp.callback.ControlPingCallback;
|
|
import org.openvpp.jvpp.callback.JVppCallback;
|
|
import org.openvpp.jvpp.dto.ControlPingReply;
|
|
|
|
/**
|
|
* Default implementation of JVppRegistry.
|
|
*/
|
|
public final class JVppRegistryImpl implements JVppRegistry, ControlPingCallback {
|
|
|
|
private static final Logger LOG = Logger.getLogger(JVppRegistryImpl.class.getName());
|
|
|
|
private final VppJNIConnection connection;
|
|
private final ConcurrentMap<String, JVppCallback> pluginRegistry;
|
|
private final ConcurrentMap<Integer, ControlPingCallback> pingCalls;
|
|
|
|
public JVppRegistryImpl(final String clientName) throws IOException {
|
|
connection = new VppJNIConnection(clientName);
|
|
connection.connect();
|
|
pluginRegistry = new ConcurrentHashMap<>();
|
|
pingCalls = new ConcurrentHashMap<>();
|
|
}
|
|
|
|
@Override
|
|
public VppConnection getConnection() {
|
|
return connection;
|
|
}
|
|
|
|
@Override
|
|
public void register(final JVpp jvpp, final JVppCallback callback) {
|
|
requireNonNull(jvpp, "jvpp should not be null");
|
|
requireNonNull(callback, "Callback should not be null");
|
|
final String name = jvpp.getClass().getName();
|
|
if (pluginRegistry.putIfAbsent(name, callback) != null) {
|
|
throw new IllegalArgumentException(String.format("Callback for plugin %s was already registered", name));
|
|
}
|
|
jvpp.init(this, callback, connection.getConnectionInfo().queueAddress,
|
|
connection.getConnectionInfo().clientIndex);
|
|
}
|
|
|
|
@Override
|
|
public void unregister(final String name) {
|
|
requireNonNull(name, "Plugin name should not be null");
|
|
final JVppCallback previous = pluginRegistry.remove(name);
|
|
assertPluginWasRegistered(name, previous);
|
|
}
|
|
|
|
@Override
|
|
public JVppCallback get(final String name) {
|
|
requireNonNull(name, "Plugin name should not be null");
|
|
JVppCallback value = pluginRegistry.get(name);
|
|
assertPluginWasRegistered(name, value);
|
|
return value;
|
|
}
|
|
|
|
private native int controlPing0() throws VppInvocationException;
|
|
|
|
@Override
|
|
public int controlPing(final Class<? extends JVpp> clazz) throws VppInvocationException {
|
|
connection.checkActive();
|
|
final String name = clazz.getName();
|
|
|
|
final ControlPingCallback callback = (ControlPingCallback) pluginRegistry.get(clazz.getName());
|
|
assertPluginWasRegistered(name, callback);
|
|
|
|
int context = controlPing0();
|
|
if (context < 0) {
|
|
throw new VppInvocationException("controlPing", context);
|
|
}
|
|
|
|
pingCalls.put(context, callback);
|
|
return context;
|
|
}
|
|
|
|
|
|
@Override
|
|
public void onControlPingReply(final ControlPingReply reply) {
|
|
final ControlPingCallback callback = pingCalls.get(reply.context);
|
|
if (callback == null) {
|
|
LOG.log(Level.WARNING, "No callback was registered for reply id={0} ", reply.context);
|
|
return;
|
|
}
|
|
// pass the reply to the callback registered by the ping caller
|
|
callback.onControlPingReply(reply);
|
|
}
|
|
|
|
@Override
|
|
public void onError(final VppCallbackException ex) {
|
|
final int ctxId = ex.getCtxId();
|
|
final ControlPingCallback callback = pingCalls.get(ctxId);
|
|
if (callback == null) {
|
|
LOG.log(Level.WARNING, "No callback was registered for reply id={0} ", ctxId);
|
|
return;
|
|
}
|
|
// pass the error to the callback registered by the ping caller
|
|
callback.onError(ex);
|
|
}
|
|
|
|
private static void assertPluginWasRegistered(final String name, final JVppCallback value) {
|
|
if (value == null) {
|
|
throw new IllegalArgumentException(String.format("Callback for plugin %s is not registered", name));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void close() throws Exception {
|
|
connection.close();
|
|
}
|
|
}
|