aboutsummaryrefslogtreecommitdiffstats
path: root/vpp-api/java/jvpp-registry/org
diff options
context:
space:
mode:
Diffstat (limited to 'vpp-api/java/jvpp-registry/org')
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVpp.java56
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistry.java69
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistryImpl.java133
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/NativeLibraryLoader.java73
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppBaseCallException.java60
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppCallbackException.java47
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppConnection.java45
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppInvocationException.java33
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppJNIConnection.java137
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/ControlPingCallback.java29
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppCallback.java29
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppNotificationCallback.java24
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPing.java34
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPingReply.java30
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppDump.java24
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppNotification.java23
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReply.java24
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReplyDump.java25
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppRequest.java34
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/AbstractFutureJVppInvoker.java120
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/FutureJVppInvoker.java39
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistry.java25
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistryProvider.java28
-rw-r--r--vpp-api/java/jvpp-registry/org/openvpp/jvpp/test/ConnectionTest.java43
24 files changed, 1184 insertions, 0 deletions
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVpp.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVpp.java
new file mode 100644
index 00000000..53bae04c
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVpp.java
@@ -0,0 +1,56 @@
+/*
+ * 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 org.openvpp.jvpp.callback.JVppCallback;
+import org.openvpp.jvpp.dto.ControlPing;
+import org.openvpp.jvpp.dto.JVppRequest;
+
+/**
+ * Base interface for plugin's Java API.
+ */
+public interface JVpp extends AutoCloseable {
+
+ /**
+ * Sends request to vpp.
+ *
+ * @param request request to be sent
+ * @return unique identifer of message in message queue
+ * @throws VppInvocationException when message could not be sent
+ */
+ int send(final JVppRequest request) throws VppInvocationException;
+
+ /**
+ * Initializes plugin's Java API.
+ *
+ * @param registry plugin registry
+ * @param callback called by vpe.api message handlers
+ * @param queueAddress address of vpp shared memory queue
+ * @param clientIndex vpp client identifier
+ */
+ void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress,
+ final int clientIndex);
+
+ /**
+ * Sends control_ping message.
+ *
+ * @param controlPing request DTO
+ * @return unique identifer of message in message queue
+ * @throws VppInvocationException when message could not be sent
+ */
+ int controlPing(final ControlPing controlPing) throws VppInvocationException;
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistry.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistry.java
new file mode 100644
index 00000000..c25b6536
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistry.java
@@ -0,0 +1,69 @@
+/*
+ * 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 org.openvpp.jvpp.callback.JVppCallback;
+
+/**
+ * Manages VPP connection and stores plugin callbacks.
+ */
+public interface JVppRegistry extends AutoCloseable {
+
+ /**
+ * Vpp connection managed by the registry.
+ *
+ * @return representation of vpp connection
+ */
+ VppConnection getConnection();
+
+ /**
+ * Registers callback and initializes Java API for given plugin.
+ *
+ * @param jvpp plugin name
+ * @param callback callback provided by the plugin
+ * @throws NullPointerException if name or callback is null
+ * @throws IllegalArgumentException if plugin was already registered
+ */
+ void register(final JVpp jvpp, final JVppCallback callback);
+
+ /**
+ * Unregisters callback for the given plugin.
+ *
+ * @param name plugin name
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if plugin was not registered
+ */
+ void unregister(final String name);
+
+ /**
+ * Returns callback registered for the plugin.
+ *
+ * @param name plugin name
+ * @return callback provided by the plugin
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if plugin was not registered
+ */
+ JVppCallback get(final String name);
+
+ /**
+ * Sends control ping. Reply handler calls callback registered for give plugin.
+ *
+ * @param clazz identifies plugin that should receive ping callback
+ * @return unique identifer of message in message queue
+ */
+ int controlPing(final Class<? extends JVpp> clazz) throws VppInvocationException;
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistryImpl.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistryImpl.java
new file mode 100644
index 00000000..bb6730f4
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/JVppRegistryImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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();
+ }
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/NativeLibraryLoader.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/NativeLibraryLoader.java
new file mode 100644
index 00000000..d00c41d5
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/NativeLibraryLoader.java
@@ -0,0 +1,73 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Utility class for loading JNI libraries.
+ */
+public final class NativeLibraryLoader {
+
+ private static final Logger LOG = Logger.getLogger(NativeLibraryLoader.class.getName());
+
+ private NativeLibraryLoader() {
+ throw new UnsupportedOperationException("This utility class cannot be instantiated.");
+ }
+
+ /**
+ * Loads JNI library using class loader of the given class.
+ *
+ * @param libName name of the library to be loaded
+ */
+ public static void loadLibrary(final String libName, final Class clazz) throws IOException {
+ java.util.Objects.requireNonNull(libName, "libName should not be null");
+ java.util.Objects.requireNonNull(clazz, "clazz should not be null");
+ try (final InputStream is = clazz.getResourceAsStream('/' + libName)) {
+ if (is == null) {
+ throw new IOException("Failed to open library resource " + libName);
+ }
+ loadStream(libName, is);
+ }
+ }
+
+ private static void loadStream(final String libName, final InputStream is) throws IOException {
+ final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
+ final Path p = Files.createTempFile(libName, null, PosixFilePermissions.asFileAttribute(perms));
+ try {
+ Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
+ Runtime.getRuntime().load(p.toString());
+ } catch (Exception e) {
+ throw new IOException("Failed to load library " + p, e);
+ } finally {
+ try {
+ Files.deleteIfExists(p);
+ } catch (IOException e) {
+ LOG.log(Level.WARNING, String.format("Failed to delete temporary file %s.", p), e);
+ }
+ }
+ }
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppBaseCallException.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppBaseCallException.java
new file mode 100644
index 00000000..792af2c6
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppBaseCallException.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+/**
+ * Base exception representing failed operation of JVpp request call
+ */
+public abstract class VppBaseCallException extends Exception {
+ private final String methodName;
+ private final int errorCode;
+
+ /**
+ * Constructs an VppCallbackException with the specified api method name and error code.
+ *
+ * @param methodName name of a method, which invocation or execution failed
+ * @param errorCode negative error code value associated with this failure
+ * @throws NullPointerException if apiMethodName is null
+ */
+ public VppBaseCallException(final String methodName, final int errorCode) {
+ super(String.format("vppApi.%s failed with error code: %d", methodName, errorCode));
+ this.methodName = java.util.Objects.requireNonNull(methodName, "apiMethodName is null!");
+ this.errorCode = errorCode;
+ if(errorCode >= 0) {
+ throw new IllegalArgumentException("Error code must be < 0. Was " + errorCode +
+ " for " + methodName );
+ }
+ }
+
+ /**
+ * Returns name of a method, which invocation failed.
+ *
+ * @return method name
+ */
+ public String getMethodName() {
+ return methodName;
+ }
+
+ /**
+ * Returns the error code associated with this failure.
+ *
+ * @return a negative integer error code
+ */
+ public int getErrorCode() {
+ return errorCode;
+ }
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppCallbackException.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppCallbackException.java
new file mode 100644
index 00000000..3d2a1cb2
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppCallbackException.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+/**
+ * Callback Exception representing failed operation of JVpp request call
+ */
+public class VppCallbackException extends VppBaseCallException {
+ private final int ctxId;
+
+ /**
+ * Constructs an VppCallbackException with the specified api method name and error code.
+ *
+ * @param methodName name of a method, which invocation failed.
+ * @param ctxId api request context identifier
+ * @param errorCode negative error code value associated with this failure
+ * @throws NullPointerException if apiMethodName is null
+ */
+ public VppCallbackException(final String methodName, final int ctxId, final int errorCode ){
+ super(methodName, errorCode);
+ this.ctxId = ctxId;
+ }
+
+ /**
+ * Returns api request context identifier.
+ *
+ * @return value of context identifier
+ */
+ public int getCtxId() {
+ return ctxId;
+ }
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppConnection.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppConnection.java
new file mode 100644
index 00000000..e7055f90
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppConnection.java
@@ -0,0 +1,45 @@
+/*
+ * 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 java.io.IOException;
+
+/**
+ * Representation of a management connection to VPP.
+ */
+public interface VppConnection extends AutoCloseable {
+
+ /**
+ * Opens VppConnection for communication with VPP.
+ *
+ * @throws IOException if connection is not established
+ */
+ void connect() throws IOException;
+
+ /**
+ * Checks if this instance connection is active.
+ *
+ * @throws IllegalStateException if this instance was disconnected.
+ */
+ void checkActive();
+
+ /**
+ * Closes Vpp connection.
+ */
+ @Override
+ void close();
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppInvocationException.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppInvocationException.java
new file mode 100644
index 00000000..298bcd0a
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppInvocationException.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * Exception thrown when Vpp jAPI method invocation failed.
+ */
+public class VppInvocationException extends VppBaseCallException {
+ /**
+ * Constructs an VppApiInvocationFailedException with the specified api method name and error code.
+ *
+ * @param methodName name of a method, which invocation failed.
+ * @param errorCode negative error code value associated with this failure
+ * @throws NullPointerException if apiMethodName is null
+ */
+ public VppInvocationException(final String methodName, final int errorCode) {
+ super(methodName, errorCode);
+ }
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppJNIConnection.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppJNIConnection.java
new file mode 100644
index 00000000..f3529874
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/VppJNIConnection.java
@@ -0,0 +1,137 @@
+/*
+ * 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();
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/ControlPingCallback.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/ControlPingCallback.java
new file mode 100644
index 00000000..529ea220
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/ControlPingCallback.java
@@ -0,0 +1,29 @@
+/*
+ * 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.callback;
+
+import org.openvpp.jvpp.dto.ControlPingReply;
+
+/**
+ * Represents callback for control_ping message.
+ */
+public interface ControlPingCallback extends JVppCallback {
+
+ void onControlPingReply(ControlPingReply reply);
+
+}
+
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppCallback.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppCallback.java
new file mode 100644
index 00000000..f681e379
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppCallback.java
@@ -0,0 +1,29 @@
+/*
+ * 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.callback;
+import org.openvpp.jvpp.VppCallbackException;
+
+/**
+ * Base JVppCallback interface
+ */
+public interface JVppCallback {
+ /**
+ * onError callback handler used to report failing operation
+ * @param ex VppCallbackException object containing details about failing operation
+ */
+ void onError(VppCallbackException ex);
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppNotificationCallback.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppNotificationCallback.java
new file mode 100644
index 00000000..72a75c83
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/callback/JVppNotificationCallback.java
@@ -0,0 +1,24 @@
+/*
+ * 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.callback;
+
+/**
+* Notification callback
+*/
+public interface JVppNotificationCallback {
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPing.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPing.java
new file mode 100644
index 00000000..cc59836d
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPing.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dto;
+
+import org.openvpp.jvpp.JVpp;
+import org.openvpp.jvpp.VppInvocationException;
+
+/**
+ * Represents request DTO for control_ping message.
+ */
+public final class ControlPing implements JVppRequest {
+
+ @Override
+ public int send(final JVpp jvpp) throws VppInvocationException {
+ return jvpp.controlPing(this);
+ }
+
+}
+
+
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPingReply.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPingReply.java
new file mode 100644
index 00000000..e7efd859
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/ControlPingReply.java
@@ -0,0 +1,30 @@
+/*
+ * 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.dto;
+
+/**
+ * Represents reply DTO for control_ping message.
+ */
+public final class ControlPingReply implements JVppReply<ControlPing> {
+
+ public int context;
+ public int clientIndex;
+ public int vpePid;
+
+
+}
+
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppDump.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppDump.java
new file mode 100644
index 00000000..295bbba8
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppDump.java
@@ -0,0 +1,24 @@
+/*
+ * 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.dto;
+
+/**
+* Base interface for all dump requests
+*/
+public interface JVppDump extends JVppRequest {
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppNotification.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppNotification.java
new file mode 100644
index 00000000..7d0fecb7
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppNotification.java
@@ -0,0 +1,23 @@
+/*
+ * 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.dto;
+
+/**
+* Base interface for all notification DTOs
+*/
+public interface JVppNotification {
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReply.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReply.java
new file mode 100644
index 00000000..2f4964c4
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReply.java
@@ -0,0 +1,24 @@
+/*
+ * 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.dto;
+
+/**
+* Base interface for all reply DTOs
+*/
+public interface JVppReply<REQ extends JVppRequest> {
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReplyDump.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReplyDump.java
new file mode 100644
index 00000000..4aecedc1
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppReplyDump.java
@@ -0,0 +1,25 @@
+/*
+ * 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.dto;
+
+/**
+* Base interface for all dump replies
+*/
+public interface JVppReplyDump<REQ extends JVppRequest, RESP extends JVppReply<REQ>>
+ extends JVppReply<REQ> {
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppRequest.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppRequest.java
new file mode 100644
index 00000000..1216edf8
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/dto/JVppRequest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.dto;
+
+import org.openvpp.jvpp.JVpp;
+import org.openvpp.jvpp.VppInvocationException;
+
+/**
+* Base interface for all request DTOs
+*/
+public interface JVppRequest {
+
+ /**
+ * Invoke current operation asynchronously on VPP
+ *
+ * @return context id of this request. Can be used to track incoming response
+ */
+ int send(JVpp jvpp) throws VppInvocationException;
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/AbstractFutureJVppInvoker.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/AbstractFutureJVppInvoker.java
new file mode 100644
index 00000000..d8b105f3
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/AbstractFutureJVppInvoker.java
@@ -0,0 +1,120 @@
+/*
+ * 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.future;
+
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import org.openvpp.jvpp.JVpp;
+import org.openvpp.jvpp.JVppRegistry;
+import org.openvpp.jvpp.VppInvocationException;
+import org.openvpp.jvpp.dto.JVppDump;
+import org.openvpp.jvpp.dto.JVppReply;
+import org.openvpp.jvpp.dto.JVppReplyDump;
+import org.openvpp.jvpp.dto.JVppRequest;
+
+/**
+* Future facade on top of JVpp
+*/
+public abstract class AbstractFutureJVppInvoker implements FutureJVppInvoker {
+
+ private final JVpp jvpp;
+ private final JVppRegistry registry;
+
+ /**
+ * Guarded by self
+ */
+ private final Map<Integer, CompletableFuture<? extends JVppReply<?>>> requests;
+
+ protected AbstractFutureJVppInvoker(final JVpp jvpp, final JVppRegistry registry,
+ final Map<Integer, CompletableFuture<? extends JVppReply<?>>> requestMap) {
+ this.jvpp = Objects.requireNonNull(jvpp, "jvpp should not be null");
+ this.registry = Objects.requireNonNull(registry, "registry should not be null");
+ // Request map represents the shared state between this facade and it's callback
+ // where facade puts futures in and callback completes + removes them
+ this.requests = Objects.requireNonNull(requestMap, "Null requestMap");
+ }
+
+ protected final Map<Integer, CompletableFuture<? extends JVppReply<?>>> getRequests() {
+ return this.requests;
+ }
+
+ // TODO use Optional in Future, java8
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <REQ extends JVppRequest, REPLY extends JVppReply<REQ>> CompletionStage<REPLY> send(REQ req) {
+ synchronized(requests) {
+ try {
+ final CompletableFuture<REPLY> replyCompletableFuture;
+ final int contextId = jvpp.send(req);
+
+ if(req instanceof JVppDump) {
+ replyCompletableFuture = (CompletableFuture<REPLY>) new CompletableDumpFuture<>(contextId);
+ } else {
+ replyCompletableFuture = new CompletableFuture<>();
+ }
+
+ requests.put(contextId, replyCompletableFuture);
+ if(req instanceof JVppDump) {
+ requests.put(registry.controlPing(jvpp.getClass()), replyCompletableFuture);
+ }
+
+ // TODO in case of timeouts/missing replies, requests from the map are not removed
+ // consider adding cancel method, that would remove requests from the map and cancel
+ // associated replyCompletableFuture
+
+ return replyCompletableFuture;
+ } catch (VppInvocationException ex) {
+ final CompletableFuture<REPLY> replyCompletableFuture = new CompletableFuture<>();
+ replyCompletableFuture.completeExceptionally(ex);
+ return replyCompletableFuture;
+ }
+ }
+ }
+
+ public static final class CompletableDumpFuture<T extends JVppReplyDump<?, ?>> extends CompletableFuture<T> {
+ // The reason why this is not final is the instantiation of ReplyDump DTOs
+ // Their instantiation must be generated, so currently the DTOs are created in callback and set when first dump reponses
+ // is handled in the callback.
+ private T replyDump;
+ private final long contextId;
+
+ public CompletableDumpFuture(final long contextId) {
+ this.contextId = contextId;
+ }
+
+ public long getContextId() {
+ return contextId;
+ }
+
+ public T getReplyDump() {
+ return replyDump;
+ }
+
+ public void setReplyDump(final T replyDump) {
+ this.replyDump = replyDump;
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ jvpp.close();
+ }
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/FutureJVppInvoker.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/FutureJVppInvoker.java
new file mode 100644
index 00000000..1683bd75
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/future/FutureJVppInvoker.java
@@ -0,0 +1,39 @@
+/*
+ * 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.future;
+
+
+import org.openvpp.jvpp.dto.JVppReply;
+import org.openvpp.jvpp.dto.JVppRequest;
+
+import java.util.concurrent.CompletionStage;
+import org.openvpp.jvpp.notification.NotificationRegistryProvider;
+
+/**
+* Future facade on top of JVpp
+*/
+public interface FutureJVppInvoker extends NotificationRegistryProvider, AutoCloseable {
+
+ /**
+ * Invoke asynchronous operation on VPP
+ *
+ * @return CompletionStage with future result of an async VPP call
+ * @throws org.openvpp.jvpp.VppInvocationException when send request failed with details
+ */
+ <REQ extends JVppRequest, REPLY extends JVppReply<REQ>> CompletionStage<REPLY> send(REQ req);
+
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistry.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistry.java
new file mode 100644
index 00000000..27349f28
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistry.java
@@ -0,0 +1,25 @@
+/*
+ * 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.notification;
+
+/**
+ * Base registry for notification callbacks.
+ */
+public interface NotificationRegistry extends AutoCloseable {
+
+ void close();
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistryProvider.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistryProvider.java
new file mode 100644
index 00000000..46c534a0
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/notification/NotificationRegistryProvider.java
@@ -0,0 +1,28 @@
+/*
+ * 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.notification;
+
+/**
+ * Provides notification registry
+ */
+public interface NotificationRegistryProvider {
+
+ /**
+ * Get current notification registry instance
+ */
+ NotificationRegistry getNotificationRegistry();
+}
diff --git a/vpp-api/java/jvpp-registry/org/openvpp/jvpp/test/ConnectionTest.java b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/test/ConnectionTest.java
new file mode 100644
index 00000000..d134a1c1
--- /dev/null
+++ b/vpp-api/java/jvpp-registry/org/openvpp/jvpp/test/ConnectionTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.test;
+
+import org.openvpp.jvpp.JVppRegistry;
+import org.openvpp.jvpp.JVppRegistryImpl;
+
+/**
+ * Run using:
+ * sudo java -cp build-vpp-native/vpp-api/java/jvpp-registry-16.09.jar org.openvpp.jvpp.test.ConnectionTest
+ */
+public class ConnectionTest {
+
+ private static void testConnect() throws Exception {
+ System.out.println("Testing JNI connection with JVppRegistry");
+ JVppRegistry registry = new JVppRegistryImpl("ConnectionTest");
+ System.out.println("Successfully connected to vpp");
+
+ Thread.sleep(5000);
+
+ System.out.println("Disconnecting...");
+ registry.close();
+ Thread.sleep(1000);
+ }
+
+ public static void main(String[] args) throws Exception {
+ testConnect();
+ }
+}