summaryrefslogtreecommitdiffstats
path: root/java/jvpp-core
diff options
context:
space:
mode:
Diffstat (limited to 'java/jvpp-core')
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiExample.java100
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiReadPerfTest.java146
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiWritePerfTest.java162
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackCliApiExample.java68
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeExample.java110
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeNotificationExample.java97
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackNotificationApiExample.java88
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/CreateSubInterfaceExample.java121
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiExample.java127
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiNotificationExample.java67
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiReadPerfTest.java137
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/L2AclExample.java206
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/LispAdjacencyExample.java125
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/NotificationUtils.java52
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/examples/Readme.txt24
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/test/CallbackApiTest.java33
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/test/FutureApiTest.java79
-rw-r--r--java/jvpp-core/io/fd/vpp/jvpp/core/test/Readme.txt18
-rw-r--r--java/jvpp-core/jvpp_core.c136
-rw-r--r--java/jvpp-core/jvpp_core.h50
20 files changed, 1946 insertions, 0 deletions
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiExample.java
new file mode 100644
index 0000000..b6558ff
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiExample.java
@@ -0,0 +1,100 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVpp;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.GetNodeIndexReplyCallback;
+import io.fd.vpp.jvpp.core.callback.ShowVersionReplyCallback;
+import io.fd.vpp.jvpp.core.callback.SwInterfaceDetailsCallback;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndex;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndexReply;
+import io.fd.vpp.jvpp.core.dto.ShowVersion;
+import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import java.nio.charset.StandardCharsets;
+
+public class CallbackApiExample {
+
+ public static void main(String[] args) throws Exception {
+ testCallbackApi();
+ }
+
+ private static void testCallbackApi() throws Exception {
+ System.out.println("Testing Java callback API with JVppRegistry");
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackApiExample");
+ final JVpp jvpp = new JVppCoreImpl()) {
+ registry.register(jvpp, new TestCallback());
+
+ System.out.println("Sending ShowVersion request...");
+ final int result = jvpp.send(new ShowVersion());
+ System.out.printf("ShowVersion send result = %d%n", result);
+
+ System.out.println("Sending GetNodeIndex request...");
+ GetNodeIndex getNodeIndexRequest = new GetNodeIndex();
+ getNodeIndexRequest.nodeName = "non-existing-node".getBytes(StandardCharsets.UTF_8);
+ jvpp.send(getNodeIndexRequest);
+
+ System.out.println("Sending SwInterfaceDump request...");
+ SwInterfaceDump swInterfaceDumpRequest = new SwInterfaceDump();
+ swInterfaceDumpRequest.nameFilterValid = 0;
+ swInterfaceDumpRequest.nameFilter = "".getBytes(StandardCharsets.UTF_8);
+ jvpp.send(swInterfaceDumpRequest);
+
+ Thread.sleep(1000);
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ static class TestCallback implements GetNodeIndexReplyCallback, ShowVersionReplyCallback, SwInterfaceDetailsCallback {
+
+ @Override
+ public void onGetNodeIndexReply(final GetNodeIndexReply msg) {
+ System.out.printf("Received GetNodeIndexReply: %s%n", msg);
+ }
+
+ @Override
+ public void onShowVersionReply(final ShowVersionReply msg) {
+ System.out.printf("Received ShowVersionReply: context=%d, program=%s, version=%s, "
+ + "buildDate=%s, buildDirectory=%s%n",
+ msg.context,
+ msg.program,
+ msg.version,
+ msg.buildDate,
+ msg.buildDirectory);
+ }
+
+ @Override
+ public void onSwInterfaceDetails(final SwInterfaceDetails msg) {
+ System.out.printf("Received SwInterfaceDetails: interfaceName=%s, l2AddressLength=%d, adminUpDown=%d, "
+ + "linkUpDown=%d, linkSpeed=%d, linkMtu=%d%n",
+ msg.interfaceName, msg.l2AddressLength, msg.adminUpDown,
+ msg.linkUpDown, msg.linkSpeed, (int) msg.linkMtu);
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n", ex.getMethodName(),
+ ex.getCtxId(), ex.getErrorCode());
+ }
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiReadPerfTest.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiReadPerfTest.java
new file mode 100644
index 0000000..6ff440d
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiReadPerfTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVpp;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.ShowVersionReplyCallback;
+import io.fd.vpp.jvpp.core.dto.*;
+
+import java.util.logging.Logger;
+
+public class CallbackApiReadPerfTest {
+
+ private static final Logger LOG = Logger.getLogger(CallbackApiReadPerfTest.class.getName());
+ private static final ShowVersion REQUEST = new ShowVersion();
+
+ /**
+ *
+ * @param args - for running for one sec requires no parameter
+ * - for running for set amount of requests requires one parameters, desired REQUEST amount
+ * @throws Exception if arguments aren't String representations of numbers
+ */
+ public static void main(String[] args) throws Exception {
+ if (args.length != 0) {
+ testInvokeCounter(true, Integer.parseUnsignedInt(args[0]));
+ } else {
+ testInvokeCounter(false, 0);
+ }
+ }
+
+ /**
+ *
+ * @param setCount true = run with set amount of requests, false = run for 1 sec
+ * @param count number of request with which test should be run
+ * @throws Exception
+ */
+ private static void testInvokeCounter(boolean setCount, int count) throws Exception {
+ LOG.info("Testing callback API Invocation Counter");
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackApiReadPerfTest");
+ final JVpp jvpp = new JVppCoreImpl()) {
+ TestCallback callback = new TestCallback(count);
+ registry.register(jvpp, callback);
+ if (!setCount) {
+ for(int i = 0; i < 5; i++) {
+ callback.reset();
+ LOG.info("Starting invocation for 1sec");
+ long time = System.nanoTime();
+ do {
+ jvpp.send(REQUEST);
+ } while (System.nanoTime() - time < 1000000000 || callback.stop());
+ int replyCount = callback.getReplyCounter();
+ LOG.info(String.format("Invocation count within 1 second: %d", replyCount));
+ }
+ } else {
+ for (int i = 0; i < 5; i++) {
+ LOG.info("Starting invocations");
+ callback.reset();
+ long time = System.nanoTime();
+ for (int x = 0; x < count; x++) {
+ jvpp.send(REQUEST);
+ }
+ long timeAfter = callback.getTime();
+ LOG.info(String.format("Invocations took %d ns (%f invocations/s)", timeAfter - time,
+ count * (1000000000.0/(timeAfter - time))));
+ }
+ }
+
+
+ Thread.sleep(1000);
+ LOG.info("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ static class TestCallback implements ShowVersionReplyCallback {
+
+ private int replyCounter = 0;
+ private int count;
+ private long time = 0;
+ private boolean stop = false;
+
+ public TestCallback(int count) throws Exception {
+ this.count = count;
+ }
+
+ public int getReplyCounter() {
+ return replyCounter;
+ }
+
+ public void reset() {
+ replyCounter = 0;
+ time = 0;
+ stop = false;
+ }
+
+ public boolean stop() {
+ this.stop = true;
+ return false;
+ }
+
+ /* actual method called from VPP
+ not thread safe but since there's only one VPP thread listening for requests and calling
+ this method it's OK
+ */
+ @Override
+ public void onShowVersionReply(final ShowVersionReply msg) {
+ if (stop) {
+ return;
+ }
+ replyCounter++;
+ if (replyCounter == count ) {
+ time = System.nanoTime();
+ }
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n", ex.getMethodName(),
+ ex.getCtxId(), ex.getErrorCode());
+ }
+
+ public long getTime() throws Exception {
+ while(time == 0) {
+ Thread.sleep(1000);
+ }
+ return time;
+ }
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiWritePerfTest.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiWritePerfTest.java
new file mode 100644
index 0000000..1940ddc
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackApiWritePerfTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2017 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVpp;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.*;
+import io.fd.vpp.jvpp.core.callback.ClassifyAddDelTableReplyCallback;
+
+import java.util.logging.Logger;
+
+public class CallbackApiWritePerfTest {
+
+ private static final Logger LOG = Logger.getLogger(CallbackApiWritePerfTest.class.getName());
+ private static final ClassifyAddDelTable REQUEST = createAddDelTable();
+
+ private static ClassifyAddDelTable createAddDelTable () {
+ ClassifyAddDelTable addDelTable = new ClassifyAddDelTable();
+ addDelTable.isAdd = 1;
+ addDelTable.tableIndex = -1;
+ addDelTable.nbuckets = 2;
+ addDelTable.memorySize = 2 << 20;
+ addDelTable.nextTableIndex = ~0; // default
+ addDelTable.missNextIndex = ~0; // default
+ addDelTable.skipNVectors = 0;
+ addDelTable.matchNVectors = 1;
+ addDelTable.mask =
+ new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x00, 0x00};
+ return addDelTable;
+ };
+
+ /**
+ *
+ * @param args - for running for one sec requires no parameter
+ * - for running for set amount of requests requires one parameters, desired REQUEST amount
+ * @throws Exception if arguments aren't String representations of numbers
+ */
+ public static void main(String[] args) throws Exception {
+ if (args.length != 0) {
+ testInvokeCounter(true, Integer.parseUnsignedInt(args[0]));
+ } else {
+ testInvokeCounter(false, 0);
+ }
+ }
+
+ /**
+ *
+ * @param setCount true = run with set amount of requests, false = run for 1 sec
+ * @param count number of requests with which test should be run
+ * @throws Exception
+ */
+ private static void testInvokeCounter(boolean setCount, int count) throws Exception {
+ LOG.info("Testing callback API Invocation Counter");
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackApiWritePerfTest");
+ final JVpp jvpp = new JVppCoreImpl()) {
+ TestCallback callback = new TestCallback(count);
+ registry.register(jvpp, callback);
+ if (!setCount) {
+ for(int i = 0; i < 5; i++) {
+ callback.reset();
+ LOG.info("Starting invocation for 1sec");
+ long time = System.nanoTime();
+ do {
+ jvpp.send(REQUEST);
+ } while (System.nanoTime() - time < 1000000000 || callback.stop());
+ int replyCount = callback.getReplyCounter();
+ LOG.info(String.format("Invocation count within 1 second: %d", replyCount));
+ }
+ } else {
+ for(int i = 0; i < 5; i++) {
+ LOG.info("Starting invocations");
+ callback.reset();
+ long time = System.nanoTime();
+ for (int x = 1; x <= count; x++) {
+ jvpp.send(REQUEST);
+ }
+ long timeAfter = callback.getTime();
+ LOG.info(String.format("Invocations took %d ns (%f invocations/s)", timeAfter - time,
+ count * (1000000000.0 / (timeAfter - time))));
+ }
+ }
+
+
+ Thread.sleep(1000);
+ LOG.info("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ static class TestCallback implements ClassifyAddDelTableReplyCallback {
+
+ private int replyCounter = 0;
+ private int count;
+ private long time = 0;
+ private boolean stop = false;
+
+ public TestCallback(int count) throws Exception {
+ this.count = count;
+ }
+
+ public int getReplyCounter() {
+ return replyCounter;
+ }
+
+ public void reset() {
+ replyCounter = 0;
+ time = 0;
+ stop = false;
+ }
+
+ public boolean stop() {
+ this.stop = true;
+ return false;
+ }
+
+ /* actual method called from VPP
+ not thread safe but since there's only one VPP thread listening for requests and calling
+ this method it's OK
+ */
+ @Override
+ public void onClassifyAddDelTableReply(final ClassifyAddDelTableReply msg) {
+ if (stop) {
+ return;
+ }
+ replyCounter++;
+ if (replyCounter == count ) {
+ time = System.nanoTime();
+ }
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n", ex.getMethodName(),
+ ex.getCtxId(), ex.getErrorCode());
+ }
+
+ public long getTime() throws Exception {
+ while(time == 0) {
+ Thread.sleep(1000);
+ }
+ return time;
+ }
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackCliApiExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackCliApiExample.java
new file mode 100644
index 0000000..b692291
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackCliApiExample.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVpp;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.CliInbandReplyCallback;
+import io.fd.vpp.jvpp.core.dto.CliInband;
+import io.fd.vpp.jvpp.core.dto.CliInbandReply;
+
+import java.nio.charset.StandardCharsets;
+
+public class CallbackCliApiExample {
+
+ public static void main(String[] args) throws Exception {
+ testCallbackApi();
+ }
+
+ private static void testCallbackApi() throws Exception {
+ System.out.println("Testing Java callback API for Cli with JVppRegistry");
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackCliApiExample");
+ final JVpp jvpp = new JVppCoreImpl()) {
+ registry.register(jvpp, new TestCallback());
+
+ System.out.println("Sending CliInband request...");
+ CliInband req = new CliInband();
+ req.cmd = "create loopback interface";
+ final int result = jvpp.send(req);
+ System.out.printf("CliInband send result = %d%n", result);
+
+ Thread.sleep(1000);
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ static class TestCallback implements CliInbandReplyCallback {
+
+ @Override
+ public void onCliInbandReply(final CliInbandReply msg) {
+ System.out.printf("%s", msg.toString());
+ System.out.printf("Received CliInbandReply: context=%d, reply=%s", msg.context, msg.reply);
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n", ex.getMethodName(),
+ ex.getCtxId(), ex.getErrorCode());
+ }
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeExample.java
new file mode 100644
index 0000000..a8b9186
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeExample.java
@@ -0,0 +1,110 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.GetNodeIndexReplyCallback;
+import io.fd.vpp.jvpp.core.callback.ShowVersionReplyCallback;
+import io.fd.vpp.jvpp.core.callfacade.CallbackJVppCoreFacade;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndex;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndexReply;
+import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * CallbackJVppFacade together with CallbackJVppFacadeCallback allow for setting different callback for each request.
+ * This is more convenient than the approach shown in CallbackApiExample.
+ */
+public class CallbackJVppFacadeExample {
+
+ private static ShowVersionReplyCallback showVersionCallback1 = new ShowVersionReplyCallback() {
+ @Override
+ public void onShowVersionReply(final ShowVersionReply msg) {
+ System.out.printf("ShowVersionCallback1 received ShowVersionReply: context=%d, program=%s,"
+ + "version=%s, buildDate=%s, buildDirectory=%s%n", msg.context,
+ msg.program,
+ msg.version,
+ msg.buildDate,
+ msg.buildDirectory);
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception in showVersionCallback1: call=%s, reply=%d, context=%d%n",
+ ex.getMethodName(), ex.getErrorCode(), ex.getCtxId());
+ }
+ };
+
+ private static ShowVersionReplyCallback showVersionCallback2 = new ShowVersionReplyCallback() {
+ @Override
+ public void onShowVersionReply(final ShowVersionReply msg) {
+ System.out.printf("ShowVersionCallback2 received ShowVersionReply: context=%d, program=%s,"
+ + "version=%s, buildDate=%s, buildDirectory=%s%n", msg.context,
+ msg.program,
+ msg.version,
+ msg.buildDate,
+ msg.buildDirectory);
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception in showVersionCallback2: call=%s, reply=%d, context=%d%n",
+ ex.getMethodName(), ex.getErrorCode(), ex.getCtxId());
+ }
+
+ };
+
+ private static GetNodeIndexReplyCallback getNodeIndexCallback = new GetNodeIndexReplyCallback() {
+ @Override
+ public void onGetNodeIndexReply(final GetNodeIndexReply msg) {
+ System.out.printf("Received GetNodeIndexReply: %s%n", msg);
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception in getNodeIndexCallback: call=%s, reply=%d, context=%d%n",
+ ex.getMethodName(), ex.getErrorCode(), ex.getCtxId());
+ }
+ };
+
+ private static void testCallbackFacade() throws Exception {
+ System.out.println("Testing CallbackJVppFacade");
+
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackFacadeExample");
+ final CallbackJVppCoreFacade callbackFacade = new CallbackJVppCoreFacade(registry, new JVppCoreImpl())) {
+ System.out.println("Successfully connected to VPP");
+
+ callbackFacade.showVersion(showVersionCallback1);
+ callbackFacade.showVersion(showVersionCallback2);
+
+ GetNodeIndex getNodeIndexRequest = new GetNodeIndex();
+ getNodeIndexRequest.nodeName = "dummyNode".getBytes(StandardCharsets.UTF_8);
+ callbackFacade.getNodeIndex(getNodeIndexRequest, getNodeIndexCallback);
+
+ Thread.sleep(2000);
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ public static void main(String[] args) throws Exception {
+ testCallbackFacade();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeNotificationExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeNotificationExample.java
new file mode 100644
index 0000000..832464a
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackJVppFacadeNotificationExample.java
@@ -0,0 +1,97 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCore;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.WantInterfaceEventsReplyCallback;
+import io.fd.vpp.jvpp.core.callback.SwInterfaceEventCallback;
+import io.fd.vpp.jvpp.core.callfacade.CallbackJVppCoreFacade;
+import io.fd.vpp.jvpp.core.dto.WantInterfaceEventsReply;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceEvent;
+
+public class CallbackJVppFacadeNotificationExample {
+
+ private static void testCallbackFacade() throws Exception {
+ System.out.println("Testing CallbackJVppFacade for notifications");
+
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackFacadeExample");
+ final JVppCore jvpp = new JVppCoreImpl()) {
+ final CallbackJVppCoreFacade jvppCallbackFacade = new CallbackJVppCoreFacade(registry, jvpp);
+ System.out.println("Successfully connected to VPP");
+
+ final AutoCloseable notificationListenerReg =
+ jvppCallbackFacade.getEventRegistry().registerSwInterfaceEventCallback(
+ new SwInterfaceEventCallback() {
+ public void onSwInterfaceEvent(SwInterfaceEvent reply) {
+ System.out.printf("Received interface notification: ifc: %s%n", reply);
+ }
+
+ public void onError (VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n",
+ ex.getMethodName(), ex.getCtxId(), ex.getErrorCode());
+ }
+ });
+
+ jvppCallbackFacade.wantInterfaceEvents(NotificationUtils.getEnableInterfaceNotificationsReq(),
+ new WantInterfaceEventsReplyCallback() {
+ @Override
+ public void onWantInterfaceEventsReply(final WantInterfaceEventsReply reply) {
+ System.out.println("Interface events started");
+ }
+
+ @Override
+ public void onError(final VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n",
+ ex.getMethodName(), ex.getCtxId(), ex.getErrorCode());
+ }
+ });
+
+ System.out.println("Changing interface configuration");
+ NotificationUtils.getChangeInterfaceState().send(jvpp);
+
+ Thread.sleep(1000);
+
+ jvppCallbackFacade.wantInterfaceEvents(NotificationUtils.getDisableInterfaceNotificationsReq(),
+ new WantInterfaceEventsReplyCallback() {
+ @Override
+ public void onWantInterfaceEventsReply(final WantInterfaceEventsReply reply) {
+ System.out.println("Interface events stopped");
+ }
+
+ @Override
+ public void onError(final VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n",
+ ex.getMethodName(), ex.getCtxId(), ex.getErrorCode());
+ }
+ });
+
+ notificationListenerReg.close();
+
+ Thread.sleep(2000);
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ public static void main(String[] args) throws Exception {
+ testCallbackFacade();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackNotificationApiExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackNotificationApiExample.java
new file mode 100644
index 0000000..9ed418e
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CallbackNotificationApiExample.java
@@ -0,0 +1,88 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.getChangeInterfaceState;
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.getDisableInterfaceNotificationsReq;
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.getEnableInterfaceNotificationsReq;
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.printNotification;
+
+import io.fd.vpp.jvpp.JVpp;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.VppCallbackException;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.SwInterfaceEventCallback;
+import io.fd.vpp.jvpp.core.callback.WantInterfaceEventsReplyCallback;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceEvent;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlagsReply;
+import io.fd.vpp.jvpp.core.dto.WantInterfaceEventsReply;
+
+public class CallbackNotificationApiExample {
+
+ private static void testCallbackApi() throws Exception {
+ System.out.println("Testing Java callback API for notifications");
+ try (final JVppRegistry registry = new JVppRegistryImpl("CallbackNotificationApiExample");
+ final JVpp jvpp = new JVppCoreImpl()) {
+ registry.register(jvpp, new TestCallback());
+ System.out.println("Successfully connected to VPP");
+
+ getEnableInterfaceNotificationsReq().send(jvpp);
+ System.out.println("Interface notifications started");
+ // TODO test ifc dump which also triggers interface flags send
+
+ System.out.println("Changing interface configuration");
+ getChangeInterfaceState().send(jvpp);
+
+ // Notifications are received
+ Thread.sleep(500);
+
+ getDisableInterfaceNotificationsReq().send(jvpp);
+ System.out.println("Interface events stopped");
+
+ Thread.sleep(2000);
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ public static void main(String[] args) throws Exception {
+ testCallbackApi();
+ }
+
+ private static class TestCallback implements SwInterfaceEventCallback,
+ WantInterfaceEventsReplyCallback {
+
+ @Override
+ public void onSwInterfaceEvent(
+ final SwInterfaceEvent msg) {
+ printNotification(msg);
+ }
+
+ @Override
+ public void onWantInterfaceEventsReply(final WantInterfaceEventsReply wantInterfaceEventsReply) {
+ System.out.println("Interface notification stream updated");
+ }
+
+ @Override
+ public void onError(VppCallbackException ex) {
+ System.out.printf("Received onError exception in getNodeIndexCallback: call=%s, reply=%d, context=%d%n",
+ ex.getMethodName(), ex.getErrorCode(), ex.getCtxId());
+
+ }
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CreateSubInterfaceExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CreateSubInterfaceExample.java
new file mode 100644
index 0000000..3db6d30
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/CreateSubInterfaceExample.java
@@ -0,0 +1,121 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import static java.util.Objects.requireNonNull;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.CreateSubif;
+import io.fd.vpp.jvpp.core.dto.CreateSubifReply;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * <p>Tests sub-interface creation.<br> Equivalent to:<br>
+ *
+ * <pre>{@code
+ * vppctl create sub GigabitEthernet0/9/0 1 dot1q 100 inner-dot1q any
+ * }
+ * </pre>
+ *
+ * To verify invoke:<br>
+ * <pre>{@code
+ * vpp_api_test json
+ * vat# sw_interface_dump
+ * }
+ */
+public class CreateSubInterfaceExample {
+
+ private static SwInterfaceDump createSwInterfaceDumpRequest(final String ifaceName) {
+ SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilter = ifaceName.getBytes(StandardCharsets.UTF_8);
+ request.nameFilterValid = 1;
+ return request;
+ }
+
+ private static void requireSingleIface(final SwInterfaceDetailsReplyDump response, final String ifaceName) {
+ if (response.swInterfaceDetails.size() != 1) {
+ throw new IllegalStateException(
+ String.format("Expected one interface matching filter %s but was %d", ifaceName,
+ response.swInterfaceDetails.size()));
+ }
+ }
+
+ private static CreateSubif createSubifRequest(final int swIfIndex, final int subId) {
+ CreateSubif request = new CreateSubif();
+ request.swIfIndex = swIfIndex; // super interface id
+ request.subId = subId;
+ request.noTags = 0;
+ request.oneTag = 0;
+ request.twoTags = 1;
+ request.dot1Ad = 0;
+ request.exactMatch = 1;
+ request.defaultSub = 0;
+ request.outerVlanIdAny = 0;
+ request.innerVlanIdAny = 1;
+ request.outerVlanId = 100;
+ request.innerVlanId = 0;
+ return request;
+ }
+
+ private static void print(CreateSubifReply reply) {
+ System.out.printf("CreateSubifReply: %s%n", reply);
+ }
+
+ private static void testCreateSubInterface() throws Exception {
+ System.out.println("Testing sub-interface creation using Java callback API");
+ try (final JVppRegistry registry = new JVppRegistryImpl("CreateSubInterfaceExample");
+ final FutureJVppCoreFacade jvppFacade = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
+ System.out.println("Successfully connected to VPP");
+ Thread.sleep(1000);
+
+ final String ifaceName = "Gigabitethernet0/8/0";
+
+ final SwInterfaceDetailsReplyDump swInterfaceDetails =
+ jvppFacade.swInterfaceDump(createSwInterfaceDumpRequest(ifaceName)).toCompletableFuture().get();
+
+ requireNonNull(swInterfaceDetails, "swInterfaceDump returned null");
+ requireNonNull(swInterfaceDetails.swInterfaceDetails, "swInterfaceDetails is null");
+ requireSingleIface(swInterfaceDetails, ifaceName);
+
+ final int swIfIndex = swInterfaceDetails.swInterfaceDetails.get(0).swIfIndex;
+ final int subId = 1;
+
+ final CreateSubifReply createSubifReply =
+ jvppFacade.createSubif(createSubifRequest(swIfIndex, subId)).toCompletableFuture().get();
+ print(createSubifReply);
+
+ final String subIfaceName = "Gigabitethernet0/8/0." + subId;
+ final SwInterfaceDetailsReplyDump subIface =
+ jvppFacade.swInterfaceDump(createSwInterfaceDumpRequest(subIfaceName)).toCompletableFuture().get();
+ requireNonNull(swInterfaceDetails, "swInterfaceDump returned null");
+ requireNonNull(subIface.swInterfaceDetails, "swInterfaceDump returned null");
+ requireSingleIface(swInterfaceDetails, ifaceName);
+
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ public static void main(String[] args) throws Exception {
+ testCreateSubInterface();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiExample.java
new file mode 100644
index 0000000..030e689
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiExample.java
@@ -0,0 +1,127 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDump;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndex;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndexReply;
+import io.fd.vpp.jvpp.core.dto.ShowVersion;
+import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class FutureApiExample {
+
+ private static final Logger LOG = Logger.getLogger(FutureApiExample.class.getName());
+
+ private static void testShowVersion(final FutureJVppCoreFacade jvpp) throws Exception {
+ LOG.info("Sending ShowVersion request...");
+ final Future<ShowVersionReply> replyFuture = jvpp.showVersion(new ShowVersion()).toCompletableFuture();
+ final ShowVersionReply reply = replyFuture.get();
+ LOG.info(
+ String.format(
+ "Received ShowVersionReply: context=%d, program=%s, version=%s, buildDate=%s, buildDirectory=%s%n",
+ reply.context, reply.program,
+ reply.version,
+ reply.buildDate,
+ reply.buildDirectory));
+ }
+
+ private static void testEmptyBridgeDomainDump(final FutureJVppCoreFacade jvpp) throws Exception {
+ LOG.info("Sending ShowVersion request...");
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = -1; // dump call
+
+ final CompletableFuture<BridgeDomainDetailsReplyDump>
+ replyFuture = jvpp.bridgeDomainDump(request).toCompletableFuture();
+ final BridgeDomainDetailsReplyDump reply = replyFuture.get();
+
+ if (reply == null || reply.bridgeDomainDetails == null) {
+ LOG.severe("Received null response for empty dump: " + reply);
+ } else {
+ LOG.info(
+ String.format(
+ "Received bridge-domain dump reply with list of bridge-domains: %s",
+ reply.bridgeDomainDetails));
+ }
+ }
+
+ private static void testGetNodeIndex(final FutureJVppCoreFacade jvpp) {
+ LOG.info("Sending GetNodeIndex request...");
+ final GetNodeIndex request = new GetNodeIndex();
+ request.nodeName = "non-existing-node".getBytes(StandardCharsets.UTF_8);
+ final Future<GetNodeIndexReply> replyFuture = jvpp.getNodeIndex(request).toCompletableFuture();
+ try {
+ final GetNodeIndexReply reply = replyFuture.get();
+ LOG.info(
+ String.format(
+ "Received GetNodeIndexReply: context=%d, nodeIndex=%d%n", reply.context, reply.nodeIndex));
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "GetNodeIndex request failed", e);
+ }
+ }
+
+ private static void testSwInterfaceDump(final FutureJVppCoreFacade jvpp) throws Exception {
+ LOG.info("Sending SwInterfaceDump request...");
+ final SwInterfaceDump request = new SwInterfaceDump();
+ request.nameFilterValid = 0;
+ request.nameFilter = "".getBytes(StandardCharsets.UTF_8);
+
+ final Future<SwInterfaceDetailsReplyDump> replyFuture = jvpp.swInterfaceDump(request).toCompletableFuture();
+ final SwInterfaceDetailsReplyDump reply = replyFuture.get();
+ for (SwInterfaceDetails details : reply.swInterfaceDetails) {
+ Objects.requireNonNull(details, "reply.swInterfaceDetails contains null element!");
+ LOG.info(
+ String.format("Received SwInterfaceDetails: interfaceName=%s, l2AddressLength=%d, adminUpDown=%d, "
+ + "linkUpDown=%d, linkSpeed=%d, linkMtu=%d%n",
+ details.interfaceName,
+ details.l2AddressLength, details.adminUpDown,
+ details.linkUpDown, details.linkSpeed, (int) details.linkMtu));
+ }
+ }
+
+ private static void testFutureApi() throws Exception {
+ LOG.info("Testing Java future API");
+ try (final JVppRegistry registry = new JVppRegistryImpl("FutureApiExample");
+ final FutureJVppCoreFacade jvppFacade = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
+ LOG.info("Successfully connected to VPP");
+
+ testEmptyBridgeDomainDump(jvppFacade);
+ testShowVersion(jvppFacade);
+ testGetNodeIndex(jvppFacade);
+ testSwInterfaceDump(jvppFacade);
+
+ LOG.info("Disconnecting...");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ testFutureApi();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiNotificationExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiNotificationExample.java
new file mode 100644
index 0000000..3c84fd7
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiNotificationExample.java
@@ -0,0 +1,67 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.getChangeInterfaceState;
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.getDisableInterfaceNotificationsReq;
+import static io.fd.vpp.jvpp.core.examples.NotificationUtils.getEnableInterfaceNotificationsReq;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import io.fd.vpp.jvpp.core.callback.SwInterfaceEventCallback;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceEvent;
+import io.fd.vpp.jvpp.VppCallbackException;
+
+public class FutureApiNotificationExample {
+
+ private static void testFutureApi() throws Exception {
+ System.out.println("Testing Java future API for notifications");
+ try (final JVppRegistry registry = new JVppRegistryImpl("FutureApiNotificationExample");
+ final FutureJVppCoreFacade jvppFacade = new FutureJVppCoreFacade(registry, new JVppCoreImpl());
+ final AutoCloseable notificationListenerReg =
+ jvppFacade.getEventRegistry()
+ .registerSwInterfaceEventCallback(new SwInterfaceEventCallback() {
+ public void onSwInterfaceEvent(SwInterfaceEvent reply) {
+ System.out.printf("Received interface notification: ifc: %s%n", reply);
+ }
+
+ public void onError (VppCallbackException ex) {
+ System.out.printf("Received onError exception: call=%s, context=%d, retval=%d%n",
+ ex.getMethodName(), ex.getCtxId(), ex.getErrorCode());
+ }
+ })) {
+ System.out.println("Successfully connected to VPP");
+ jvppFacade.wantInterfaceEvents(getEnableInterfaceNotificationsReq()).toCompletableFuture().get();
+ System.out.println("Interface events started");
+
+ System.out.println("Changing interface configuration");
+ jvppFacade.swInterfaceSetFlags(getChangeInterfaceState()).toCompletableFuture().get();
+
+ Thread.sleep(1000);
+
+ jvppFacade.wantInterfaceEvents(getDisableInterfaceNotificationsReq()).toCompletableFuture().get();
+ System.out.println("Interface events stopped");
+ System.out.println("Disconnecting...");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ testFutureApi();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiReadPerfTest.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiReadPerfTest.java
new file mode 100644
index 0000000..f335b28
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/FutureApiReadPerfTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.callback.ShowVersionReplyCallback;
+import io.fd.vpp.jvpp.core.dto.*;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.logging.Logger;
+
+public class FutureApiReadPerfTest {
+
+ private static final Logger LOG = Logger.getLogger(FutureApiReadPerfTest.class.getName());
+ private static final ShowVersion REQUEST = new ShowVersion();
+ private static volatile int currentCount = 0;
+ private static int desiredCount = 0;
+ private static long timeAfter = 0;
+ private static volatile boolean stop = false;
+ /**
+ * Run after reply message is received
+ * in case of running for 1 sec check if time passed (stop variable) and if it does skip processing
+ * in case of running for set amount of REQUEST, record time in which was last reply received
+ * not thread save but since reading part process only one message at a time it's ok
+ */
+ private static Runnable replyFc = () -> {
+ if (stop) {
+ return;
+ }
+ currentCount++;
+ if(currentCount == desiredCount) {
+ timeAfter = System.nanoTime();
+ }
+ };
+
+ /**
+ * Used to reset counters and flags between runs
+ */
+ private static void reset() {
+ currentCount = 0;
+ timeAfter = 0;
+ stop = false;
+ }
+
+ public static boolean stop() {
+ stop = true;
+ return false;
+ }
+
+ /**
+ *
+ * @return time of last reply received
+ * @throws Exception during thread sleep
+ */
+ private static long getTime() throws Exception {
+ while(timeAfter == 0) {
+ LOG.info(String.format("Received %d replies", currentCount));
+ Thread.sleep(1000);
+ }
+ return timeAfter;
+ }
+
+ /**
+ *
+ * @param args - for running for one sec requires no parameter
+ * - for running for set amount of requests requires one parameters, desired REQUEST amount
+ * @throws Exception if arguments aren't String representations of numbers
+ */
+ public static void main(String[] args) throws Exception {
+ if (args.length == 1) {
+ desiredCount = Integer.parseUnsignedInt(args[0]);
+ testInvokeCounter(true);
+ } else {
+ testInvokeCounter(false);
+ }
+ }
+
+ /**
+ *
+ * @param setCount true = run with set amount of requests, false = run for 1 sec
+ * @throws Exception
+ */
+ private static void testInvokeCounter(boolean setCount) throws Exception {
+ LOG.info("Testing callback API Invocation Counter");
+ try (final JVppRegistry registry = new JVppRegistryImpl("FutureApiReadPerfTest");
+ final FutureJVppCoreFacade jvpp = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
+ if (!setCount) {
+ for(int i = 0; i < 5; i++) {
+ reset();
+ LOG.info("Starting invocation for 1sec");
+ long time = System.nanoTime();
+ do {
+ CompletableFuture<ShowVersionReply> replyFuture = jvpp.showVersion(REQUEST).toCompletableFuture();
+ replyFuture.thenRun(replyFc);
+ } while (System.nanoTime() - time < 1000000000 || stop());
+ LOG.info(String.format("Invocation count within 1 second: %d", currentCount));
+ }
+ } else {
+ for (int i = 0; i < 5; i++) {
+ LOG.info("Starting invocations");
+ reset();
+ long time = System.nanoTime();
+ for (int x = 0; x < desiredCount; x++) {
+ CompletableFuture<ShowVersionReply> replyFuture = jvpp.showVersion(REQUEST).toCompletableFuture();
+ replyFuture.thenRun(replyFc);
+ }
+ LOG.info("Invocations send");
+ long timeAfter = getTime();
+ LOG.info(String.format("Invocations took %d ns (%f invocations/s)", timeAfter - time,
+ desiredCount * (1000000000.0/(timeAfter - time))));
+ }
+ }
+
+
+ Thread.sleep(1000);
+ LOG.info("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/L2AclExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/L2AclExample.java
new file mode 100644
index 0000000..0be85d4
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/L2AclExample.java
@@ -0,0 +1,206 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSession;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelSessionReply;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTable;
+import io.fd.vpp.jvpp.core.dto.ClassifyAddDelTableReply;
+import io.fd.vpp.jvpp.core.dto.ClassifySessionDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.ClassifySessionDump;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableIds;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableIdsReply;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableInfo;
+import io.fd.vpp.jvpp.core.dto.ClassifyTableInfoReply;
+import io.fd.vpp.jvpp.core.dto.InputAclSetInterface;
+import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+
+/**
+ * <p>Tests L2 ACL creation and read.<br> Equivalent to the following vppctl commands:<br>
+ *
+ * <pre>{@code
+ * vppctl classify table mask l2 src
+ * vppctl classify session acl-hit-next deny opaque-index 0 table-index 0 match l2 src 01:02:03:04:05:06
+ * vppctl set int input acl intfc local0 l2-table 0
+ * vppctl sh class table verbose
+ * }
+ * </pre>
+ */
+public class L2AclExample {
+
+ private static final int LOCAL0_IFACE_ID = 0;
+ private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
+
+
+ private static ClassifyAddDelTable createClassifyTable() {
+ ClassifyAddDelTable request = new ClassifyAddDelTable();
+ request.isAdd = 1;
+ request.tableIndex = ~0; // default
+ request.nbuckets = 2;
+ request.memorySize = 2 << 20;
+ request.nextTableIndex = ~0; // default
+ request.missNextIndex = ~0; // default
+ request.skipNVectors = 0;
+ request.matchNVectors = 1;
+ request.mask =
+ new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, 0x00, 0x00, 0x00, 0x00};
+ return request;
+ }
+
+ private static String bytesToHex(byte[] bytes) {
+ char[] hexChars = new char[bytes.length * 2];
+ for ( int j = 0; j < bytes.length; j++ ) {
+ int v = bytes[j] & 0xFF;
+ hexChars[j * 2] = hexArray[v >>> 4];
+ hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+ }
+ return new java.lang.String(hexChars);
+ }
+
+ private static ClassifyTableInfo createClassifyTableInfoRequest(final int tableId) {
+ ClassifyTableInfo request = new ClassifyTableInfo();
+ request.tableId = tableId;
+ return request;
+ }
+
+ private static ClassifyAddDelSession createClassifySession(final int tableIndex) {
+ ClassifyAddDelSession request = new ClassifyAddDelSession();
+ request.isAdd = 1;
+ request.tableIndex = tableIndex;
+ request.hitNextIndex = 0; // deny
+ request.opaqueIndex = 0;
+ request.advance = 0; // default
+ // match 01:02:03:04:05:06 mac address
+ request.match =
+ new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+ (byte) 0x05, (byte) 0x06, 0x00, 0x00, 0x00, 0x00};
+ return request;
+ }
+
+ private static ClassifySessionDump createClassifySessionDumpRequest(final int newTableIndex) {
+ ClassifySessionDump request = new ClassifySessionDump();
+ request.tableId = newTableIndex;
+ return request;
+ }
+
+ private static InputAclSetInterface aclSetInterface() {
+ InputAclSetInterface request = new InputAclSetInterface();
+ request.isAdd = 1;
+ request.swIfIndex = LOCAL0_IFACE_ID;
+ request.ip4TableIndex = ~0; // skip
+ request.ip6TableIndex = ~0; // skip
+ request.l2TableIndex = 0;
+ return request;
+ }
+
+ private static ClassifyTableByInterface createClassifyTableByInterfaceRequest() {
+ ClassifyTableByInterface request = new ClassifyTableByInterface();
+ request.swIfIndex = LOCAL0_IFACE_ID;
+ return request;
+ }
+
+ private static void print(ClassifyAddDelTableReply reply) {
+ System.out.printf("ClassifyAddDelTableReply: %s%n", reply);
+ }
+
+ private static void print(ClassifyTableIdsReply reply) {
+ System.out.printf("ClassifyTableIdsReply: %s%n", reply);
+ }
+
+ private static void print(final ClassifyTableInfoReply reply) {
+ System.out.println(reply);
+ if (reply != null) {
+ System.out.println("Mask hex: " + bytesToHex(reply.mask));
+ }
+ }
+
+ private static void print(ClassifyAddDelSessionReply reply) {
+ System.out.printf("ClassifyAddDelSessionReply: context=%s%n", reply);
+ }
+
+ private static void print(final ClassifySessionDetailsReplyDump reply) {
+ System.out.println(reply);
+ reply.classifySessionDetails.forEach(detail -> {
+ System.out.println(detail);
+ System.out.println("Match hex: " + bytesToHex(detail.match));
+ });
+ }
+
+ private static void print(final InputAclSetInterfaceReply reply) {
+ System.out.printf("InputAclSetInterfaceReply: context=%s%n", reply);
+ }
+
+ private static void print(final ClassifyTableByInterfaceReply reply) {
+ System.out.printf("ClassifyAddDelTableReply: %s%n", reply);
+ }
+
+ private static void testL2Acl() throws Exception {
+ System.out.println("Testing L2 ACLs using Java callback API");
+ try (final JVppRegistry registry = new JVppRegistryImpl("L2AclExample");
+ final FutureJVppCoreFacade jvppFacade = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
+
+ System.out.println("Successfully connected to VPP");
+ Thread.sleep(1000);
+
+ final ClassifyAddDelTableReply classifyAddDelTableReply =
+ jvppFacade.classifyAddDelTable(createClassifyTable()).toCompletableFuture().get();
+ print(classifyAddDelTableReply);
+
+ final ClassifyTableIdsReply classifyTableIdsReply =
+ jvppFacade.classifyTableIds(new ClassifyTableIds()).toCompletableFuture().get();
+ print(classifyTableIdsReply);
+
+ final ClassifyTableInfoReply classifyTableInfoReply =
+ jvppFacade.classifyTableInfo(createClassifyTableInfoRequest(classifyAddDelTableReply.newTableIndex))
+ .toCompletableFuture().get();
+ print(classifyTableInfoReply);
+
+ final ClassifyAddDelSessionReply classifyAddDelSessionReply =
+ jvppFacade.classifyAddDelSession(createClassifySession(classifyAddDelTableReply.newTableIndex))
+ .toCompletableFuture().get();
+ print(classifyAddDelSessionReply);
+
+ final ClassifySessionDetailsReplyDump classifySessionDetailsReplyDump =
+ jvppFacade.classifySessionDump(createClassifySessionDumpRequest(classifyAddDelTableReply.newTableIndex))
+ .toCompletableFuture().get();
+ print(classifySessionDetailsReplyDump);
+
+ final InputAclSetInterfaceReply inputAclSetInterfaceReply =
+ jvppFacade.inputAclSetInterface(aclSetInterface()).toCompletableFuture().get();
+ print(inputAclSetInterfaceReply);
+
+ final ClassifyTableByInterfaceReply classifyTableByInterfaceReply =
+ jvppFacade.classifyTableByInterface(createClassifyTableByInterfaceRequest()).toCompletableFuture()
+ .get();
+ print(classifyTableByInterfaceReply);
+
+ System.out.println("Disconnecting...");
+ }
+ Thread.sleep(1000);
+ }
+
+ public static void main(String[] args) throws Exception {
+ testL2Acl();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/LispAdjacencyExample.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/LispAdjacencyExample.java
new file mode 100644
index 0000000..f637669
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/LispAdjacencyExample.java
@@ -0,0 +1,125 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.LispAddDelAdjacency;
+import io.fd.vpp.jvpp.core.dto.LispAddDelLocalEid;
+import io.fd.vpp.jvpp.core.dto.LispAddDelLocatorSet;
+import io.fd.vpp.jvpp.core.dto.LispAddDelRemoteMapping;
+import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGet;
+import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGetReply;
+import io.fd.vpp.jvpp.core.dto.LispEnableDisable;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Logger;
+
+/**
+ * Tests lisp adjacency creation and read (custom vpe.api type support showcase).
+ */
+public class LispAdjacencyExample {
+
+ private static final Logger LOG = Logger.getLogger(LispAdjacencyExample.class.getName());
+
+ private static void enableLisp(final FutureJVppCoreFacade jvpp) throws ExecutionException, InterruptedException {
+ final LispEnableDisable request = new LispEnableDisable();
+ request.isEn = 1;
+ jvpp.lispEnableDisable(request).toCompletableFuture().get();
+ LOG.info("Lisp enabled successfully");
+ }
+
+ private static void addLocatorSet(final FutureJVppCoreFacade jvpp) throws ExecutionException, InterruptedException {
+ final LispAddDelLocatorSet request = new LispAddDelLocatorSet();
+ request.isAdd = 1;
+ request.locatorSetName = "ls1".getBytes(StandardCharsets.UTF_8);
+ jvpp.lispAddDelLocatorSet(request).toCompletableFuture().get();
+ LOG.info("Locator set created successfully:" + request.toString());
+ }
+
+ private static void addLocalEid(final FutureJVppCoreFacade jvpp) throws ExecutionException, InterruptedException {
+ final LispAddDelLocalEid request = new LispAddDelLocalEid();
+ request.isAdd = 1;
+ request.locatorSetName = "ls1".getBytes(StandardCharsets.UTF_8);
+ request.eid = new byte[] {1, 2, 1, 10};
+ request.eidType = 0; // ip4
+ request.vni = 0;
+ request.prefixLen = 32;
+ jvpp.lispAddDelLocalEid(request).toCompletableFuture().get();
+ LOG.info("Local EID created successfully:" + request.toString());
+ }
+
+ private static void addRemoteMapping(final FutureJVppCoreFacade jvpp)
+ throws ExecutionException, InterruptedException {
+ final LispAddDelRemoteMapping request = new LispAddDelRemoteMapping();
+ request.isAdd = 1;
+ request.vni = 0;
+ request.eid = new byte[] {1, 2, 1, 20};
+ request.eidLen = 32;
+ request.rlocNum = 1;
+ // FIXME!!!!
+ //request.rlocs = new byte[] {1, 1, 1, 1, 2, 1, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ jvpp.lispAddDelRemoteMapping(request).toCompletableFuture().get();
+ LOG.info("Remote mapping created successfully:" + request.toString());
+ }
+
+ private static void addAdjacency(final FutureJVppCoreFacade jvpp) throws ExecutionException, InterruptedException {
+ final LispAddDelAdjacency request = new LispAddDelAdjacency();
+ request.isAdd = 1;
+ request.leid = new byte[] {1, 2, 1, 10};
+ request.leidLen = 32;
+ request.reid = new byte[] {1, 2, 1, 20};
+ request.reidLen = 32;
+ request.eidType = 0; // ip4
+ request.vni = 0;
+ jvpp.lispAddDelAdjacency(request).toCompletableFuture().get();
+ LOG.info("Lisp adjacency created successfully:" + request.toString());
+ }
+
+ private static void showAdjacencies(final FutureJVppCoreFacade jvpp)
+ throws ExecutionException, InterruptedException {
+ final LispAdjacenciesGetReply reply =
+ jvpp.lispAdjacenciesGet(new LispAdjacenciesGet()).toCompletableFuture().get();
+ LOG.info("Lisp adjacency received successfully:" + reply.toString());
+ }
+
+ private static void testAdjacency(final FutureJVppCoreFacade jvpp) throws Exception {
+ enableLisp(jvpp);
+ addLocatorSet(jvpp);
+ addLocalEid(jvpp);
+ addRemoteMapping(jvpp);
+ addAdjacency(jvpp);
+ showAdjacencies(jvpp);
+ }
+
+ private static void testFutureApi() throws Exception {
+ LOG.info("Create lisp adjacency test");
+ try (final JVppRegistry registry = new JVppRegistryImpl("LispAdjacencyExample");
+ final FutureJVppCoreFacade jvppFacade = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
+ LOG.info("Successfully connected to VPP");
+
+ testAdjacency(jvppFacade);
+ LOG.info("Disconnecting...");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ testFutureApi();
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/NotificationUtils.java b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/NotificationUtils.java
new file mode 100644
index 0000000..e963d63
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/NotificationUtils.java
@@ -0,0 +1,52 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.examples;
+
+import java.io.PrintStream;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceSetFlags;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceEvent;
+import io.fd.vpp.jvpp.core.dto.WantInterfaceEvents;
+
+final class NotificationUtils {
+
+ private NotificationUtils() {}
+
+ static PrintStream printNotification(final SwInterfaceEvent msg) {
+ return System.out.printf("Received interface notification: ifc: %s%n", msg);
+ }
+
+ static SwInterfaceSetFlags getChangeInterfaceState() {
+ final SwInterfaceSetFlags swInterfaceSetFlags = new SwInterfaceSetFlags();
+ swInterfaceSetFlags.swIfIndex = 0;
+ swInterfaceSetFlags.adminUpDown = 1;
+ return swInterfaceSetFlags;
+ }
+
+ static WantInterfaceEvents getEnableInterfaceNotificationsReq() {
+ WantInterfaceEvents wantInterfaceEvents = new WantInterfaceEvents();
+ wantInterfaceEvents.pid = 1;
+ wantInterfaceEvents.enableDisable = 1;
+ return wantInterfaceEvents;
+ }
+
+ static WantInterfaceEvents getDisableInterfaceNotificationsReq() {
+ WantInterfaceEvents wantInterfaceEvents = new WantInterfaceEvents();
+ wantInterfaceEvents.pid = 1;
+ wantInterfaceEvents.enableDisable = 0;
+ return wantInterfaceEvents;
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/examples/Readme.txt b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/Readme.txt
new file mode 100644
index 0000000..9fe3c7a
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/examples/Readme.txt
@@ -0,0 +1,24 @@
+This package contains basic examples for jvpp. To run the examples:
+
+- Make sure VPP is running
+- From VPP's build-root/ folder execute:
+ - release version: sudo java -cp build-vpp-native/vpp/vpp-api/java/jvpp-registry-18.01.jar:build-vpp-native/vpp/vpp-api/java/jvpp-core-18.01.jar io.fd.vpp.jvpp.core.examples.[test name]
+ - debug version: sudo java -cp build-vpp_debug-native/vpp/vpp-api/java/jvpp-registry-18.01.jar:build-vpp_debug-native/vpp/vpp-api/java/jvpp-core-18.01.jar io.fd.vpp.jvpp.core.examples.[test name]
+
+Available examples:
+CallbackApiExample - Similar to ControlPingTest, invokes more complex calls (e.g. interface dump) using low level JVpp APIs
+CallbackJVppFacadeNotificationExample - Example of interface notifications using Callback based JVpp facade
+CallbackJVppFacadeExample - Execution of more complex calls using Callback based JVpp facade
+CallbackNotificationApiExample - Example of interface notifications using low level JVpp APIs
+CreateSubInterfaceExample - Example of sub-interface creation
+FutureApiNotificationExample - Example of interface notifications using Future based JVpp facade
+FutureApiExample - Execution of more complex calls using Future based JVpp facade
+L2AclExample - Example of L2 ACL creation
+LispAdjacencyExample - Example of lisp adjacency creation and read (custom vpe.api type support showcase)
+
+CallbackApiReadPerfTest, FutureApiReadPerfTest, CallbackApiWritePerfTest - test provide two ways to count invocations:
+1) maximum number of invocations and received replyies within 1 sec
+sudo java -cp build-vpp-native/vpp/vpp-api/java/jvpp-registry-18.01.jar:build-vpp-native/vpp/vpp-api/java/jvpp-core-18.01.jar io.fd.vpp.jvpp.core.examples.[test name]
+2) measure time in ns from first request to receiving last reply over set amount of requests
+sudo java -cp build-vpp-native/vpp/vpp-api/java/jvpp-registry-18.01.jar:build-vpp-native/vpp/vpp-api/java/jvpp-core-18.01.jar io.fd.vpp.jvpp.core.examples.[test name] [number of request to send]
+
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/test/CallbackApiTest.java b/java/jvpp-core/io/fd/vpp/jvpp/core/test/CallbackApiTest.java
new file mode 100644
index 0000000..493116c
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/test/CallbackApiTest.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 io.fd.vpp.jvpp.core.test;
+
+import io.fd.vpp.jvpp.AbstractCallbackApiTest;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+
+import java.util.logging.Logger;
+
+public class CallbackApiTest extends AbstractCallbackApiTest {
+
+ private static Logger LOG = Logger.getLogger(CallbackApiTest.class.getName());
+
+
+ public static void main(String[] args) throws Exception {
+ LOG.info("Testing ControlPing using Java callback API for core plugin");
+ testControlPing(args[0], new JVppCoreImpl());
+ }
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/test/FutureApiTest.java b/java/jvpp-core/io/fd/vpp/jvpp/core/test/FutureApiTest.java
new file mode 100644
index 0000000..d3acecc
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/test/FutureApiTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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 io.fd.vpp.jvpp.core.test;
+
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.JVppRegistryImpl;
+import io.fd.vpp.jvpp.core.JVppCoreImpl;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.BridgeDomainDump;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndex;
+import io.fd.vpp.jvpp.core.dto.GetNodeIndexReply;
+import io.fd.vpp.jvpp.core.dto.ShowVersion;
+import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetails;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SwInterfaceDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class FutureApiTest {
+
+ private static final Logger LOG = Logger.getLogger(FutureApiTest.class.getName());
+
+ public static void main(String[] args) throws Exception {
+ testFutureApi(args);
+ }
+
+ private static void testFutureApi(String[] args) throws Exception {
+ LOG.info("Testing Java future API for core plugin");
+ try (final JVppRegistry registry = new JVppRegistryImpl("FutureApiTest", args[0]);
+ final FutureJVppCoreFacade jvppFacade = new FutureJVppCoreFacade(registry, new JVppCoreImpl())) {
+ LOG.info("Successfully connected to VPP");
+
+ testEmptyBridgeDomainDump(jvppFacade);
+
+ LOG.info("Disconnecting...");
+ }
+ }
+
+ private static void testEmptyBridgeDomainDump(final FutureJVppCoreFacade jvpp) throws Exception {
+ LOG.info("Sending BridgeDomainDump request...");
+ final BridgeDomainDump request = new BridgeDomainDump();
+ request.bdId = -1; // dump call
+
+ final CompletableFuture<BridgeDomainDetailsReplyDump>
+ replyFuture = jvpp.bridgeDomainDump(request).toCompletableFuture();
+ final BridgeDomainDetailsReplyDump reply = replyFuture.get();
+
+ if (reply == null || reply.bridgeDomainDetails == null) {
+ throw new IllegalStateException("Received null response for empty dump: " + reply);
+ } else {
+ LOG.info(
+ String.format(
+ "Received bridge-domain dump reply with list of bridge-domains: %s",
+ reply.bridgeDomainDetails));
+ }
+ }
+
+
+}
diff --git a/java/jvpp-core/io/fd/vpp/jvpp/core/test/Readme.txt b/java/jvpp-core/io/fd/vpp/jvpp/core/test/Readme.txt
new file mode 100644
index 0000000..b74cf60
--- /dev/null
+++ b/java/jvpp-core/io/fd/vpp/jvpp/core/test/Readme.txt
@@ -0,0 +1,18 @@
+This package contains basic tests for jvpp. To run the tests:
+
+- Make sure VPP is running
+- From VPP's build-root/ folder execute:
+ - release version: sudo java -cp build-vpp-native/vpp/vpp-api/java/jvpp-registry-17.10.jar:build-vpp-native/vpp/vpp-api/java/jvpp-core-17.10.jar io.fd.vpp.jvpp.core.test.[test name]
+ - debug version: sudo java -cp build-vpp_debug-native/vpp/vpp-api/java/jvpp-registry-17.10.jar:build-vpp_debug-native/vpp/vpp-api/java/jvpp-core-17.10.jar io.fd.vpp.jvpp.core.test.[test name]
+
+Available tests:
+CallbackApiTest - Similar to ControlPingTest, invokes more complex calls (e.g. interface dump) using low level JVpp APIs
+CallbackJVppFacadeNotificationTest - Tests interface notifications using Callback based JVpp facade
+CallbackJVppFacadeTest - Execution of more complex calls using Callback based JVpp facade
+CallbackNotificationApiTest - Tests interface notifications using low level JVpp APIs
+ControlPingTest - Simple test executing a single control ping using low level JVpp APIs
+CreateSubInterfaceTest - Tests sub-interface creation
+FutureApiNotificationTest - Tests interface notifications using Future based JVpp facade
+FutureApiTest - Execution of more complex calls using Future based JVpp facade
+L2AclTest - Tests L2 ACL creation
+LispAdjacencyTest - Tests lisp adjacency creation and read (custom vpe.api type support showcase)
diff --git a/java/jvpp-core/jvpp_core.c b/java/jvpp-core/jvpp_core.c
new file mode 100644
index 0000000..2e62426
--- /dev/null
+++ b/java/jvpp-core/jvpp_core.c
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+#include <vnet/vnet.h>
+#include <jvpp-common/jvpp_common.h>
+#include <vpp/api/vpe_msg_enum.h>
+#define vl_typedefs /* define message structures */
+#include <vpp/api/vpe_all_api_h.h>
+#undef vl_typedefs
+
+#include <vnet/api_errno.h>
+#include <vlibapi/api.h>
+#include <vlibmemory/api.h>
+#include <jni.h>
+#include <jvpp_core.h>
+
+
+// TODO: generate jvpp_plugin_name.c files (or at least reuse plugin's main structure)
+typedef struct {
+ /* Pointer to shared memory queue */
+ svm_queue_t * vl_input_queue;
+
+ /* VPP api client index */
+ u32 my_client_index;
+
+ /* Callback object and class references enabling asynchronous Java calls */
+ jobject callbackObject;
+ jclass callbackClass;
+
+} core_main_t;
+
+core_main_t core_main __attribute__((aligned (64)));
+
+#include "io_fd_vpp_jvpp_core_JVppCoreImpl.h"
+#include "jvpp_core_gen.h"
+
+JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_core_JVppCoreImpl_init0
+(JNIEnv * env, jclass clazz, jobject callback, jlong queue_address, jint my_client_index) {
+ core_main_t * plugin_main = &core_main;
+ plugin_main->my_client_index = my_client_index;
+ plugin_main->vl_input_queue = uword_to_pointer (queue_address, svm_queue_t *);
+
+ plugin_main->callbackObject = (*env)->NewGlobalRef(env, callback);
+ plugin_main->callbackClass = (jclass)(*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, callback));
+
+ // verify API has not changed since jar generation (exit on mismatch)
+ #define _(N) \
+ if (get_message_id(env, #N) == 0) return;
+ foreach_supported_api_message;
+ #undef _
+
+ #define _(N,n) \
+ vl_msg_api_set_handlers(get_message_id(env, #N), #n, \
+ vl_api_##n##_t_handler, \
+ vl_noop_handler, \
+ vl_noop_handler, \
+ vl_noop_handler, \
+ sizeof(vl_api_##n##_t), 1);
+ foreach_api_reply_handler;
+ #undef _
+}
+
+JNIEXPORT void JNICALL Java_io_fd_vpp_jvpp_core_JVppCoreImpl_close0
+(JNIEnv *env, jclass clazz) {
+ core_main_t * plugin_main = &core_main;
+
+ // cleanup:
+ (*env)->DeleteGlobalRef(env, plugin_main->callbackClass);
+ (*env)->DeleteGlobalRef(env, plugin_main->callbackObject);
+
+ plugin_main->callbackClass = NULL;
+ plugin_main->callbackObject = NULL;
+}
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv* env;
+
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) {
+ return JNI_EVERSION;
+ }
+
+ if (cache_class_references(env) != 0) {
+ clib_warning ("Failed to cache class references\n");
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_8;
+}
+
+void JNI_OnUnload(JavaVM *vm, void *reserved) {
+ JNIEnv* env;
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_8) != JNI_OK) {
+ return;
+ }
+ delete_class_references(env);
+}
+
+
+static void _host_to_net_string(JNIEnv * env, jstring javaString, vl_api_string_t * vl_api_string)
+{
+ const char *nativeString;
+ // prevent null, which causes jni to crash
+ if (NULL != javaString) {
+ nativeString = (*env)->GetStringUTFChars(env, javaString, 0);
+ } else{
+ nativeString = "";
+ }
+
+ vl_api_to_api_string(jstr_length(env, javaString) + 1, nativeString, vl_api_string);
+
+ (*env)->ReleaseStringUTFChars(env, javaString, nativeString);
+}
+
+
+static jstring _net_to_host_string(JNIEnv * env, const vl_api_string_t * _net)
+{
+ return (*env)->NewStringUTF(env, (char *)_net->buf);
+}
+
+
+static size_t jstr_length(JNIEnv *env, jstring string)
+{
+ return ((int) (*env)->GetStringUTFLength(env, string));
+}
diff --git a/java/jvpp-core/jvpp_core.h b/java/jvpp-core/jvpp_core.h
new file mode 100644
index 0000000..032dd33
--- /dev/null
+++ b/java/jvpp-core/jvpp_core.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef VPP_JVPP_CORE_H
+#define VPP_JVPP_CORE_H
+
+#include <vlibapi/api_types.h>
+
+#endif //VPP_JVPP_CORE_H
+
+// /**
+// * Host to network byte order conversion for string type. Converts String in Java to VPP string type.
+// * typedef struct
+// * {
+// * u32 length;
+// * u8 buf[0];
+// * } __attribute__ ((packed)) vl_api_string_t;
+// */
+static void _host_to_net_string(JNIEnv * env, jstring javaString, vl_api_string_t * vl_api_string);
+
+
+//
+// /**
+// * Network to host byte order conversion for string type. Converts VPP string type to String in Java
+// * typedef struct
+// * {
+// * u32 length;
+// * u8 buf[0];
+// * } __attribute__ ((packed)) vl_api_string_t;
+// */
+static jstring _net_to_host_string(JNIEnv * env, const vl_api_string_t * _net);
+
+
+//
+// /**
+// * Returns the length of jstring as size_t
+// */
+static size_t jstr_length(JNIEnv *env, jstring string);