From e1c702fef2fa7c0e21b4c6d850048c898e4ccfc8 Mon Sep 17 00:00:00 2001 From: Michal Cmarada Date: Wed, 15 May 2019 09:44:11 +0200 Subject: Add dump for interface names from stats api Change-Id: I051ce7500bbbef1088bbdd6f1cc68eb605f3ec61 Signed-off-by: Michal Cmarada --- java/jvpp-stats/io/fd/jvpp/stats/JVppStats.java | 2 + .../jvpp-stats/io/fd/jvpp/stats/JVppStatsImpl.java | 13 ++++ .../callback/InterfaceNamesDetailsCallback.java | 25 ++++++++ .../stats/callback/JVppStatsGlobalCallback.java | 3 +- .../CallbackJVppStatsFacadeCallback.java | 17 ++++++ .../io/fd/jvpp/stats/dto/InterfaceName.java | 55 +++++++++++++++++ .../fd/jvpp/stats/dto/InterfaceNamesDetails.java | 71 ++++++++++++++++++++++ .../stats/dto/InterfaceNamesDetailsReplyDump.java | 54 ++++++++++++++++ .../io/fd/jvpp/stats/dto/InterfaceNamesDump.java | 51 ++++++++++++++++ .../io/fd/jvpp/stats/future/FutureJVppStats.java | 4 ++ .../jvpp/stats/future/FutureJVppStatsFacade.java | 8 +++ .../future/FutureJVppStatsFacadeCallback.java | 28 +++++++++ .../io/fd/jvpp/stats/test/FutureApiNamesTest.java | 62 +++++++++++++++++++ 13 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 java/jvpp-stats/io/fd/jvpp/stats/callback/InterfaceNamesDetailsCallback.java create mode 100644 java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceName.java create mode 100644 java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetails.java create mode 100644 java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetailsReplyDump.java create mode 100644 java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDump.java create mode 100644 java/jvpp-stats/io/fd/jvpp/stats/test/FutureApiNamesTest.java (limited to 'java/jvpp-stats/io/fd/jvpp/stats') diff --git a/java/jvpp-stats/io/fd/jvpp/stats/JVppStats.java b/java/jvpp-stats/io/fd/jvpp/stats/JVppStats.java index c4f22dc..39ae750 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/JVppStats.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/JVppStats.java @@ -28,4 +28,6 @@ public interface JVppStats extends io.fd.jvpp.JVpp { int send(io.fd.jvpp.dto.JVppRequest request) throws io.fd.jvpp.VppInvocationException; int interfaceStatisticsDump() throws io.fd.jvpp.VppInvocationException; + + int interfaceNamesDump() throws io.fd.jvpp.VppInvocationException; } diff --git a/java/jvpp-stats/io/fd/jvpp/stats/JVppStatsImpl.java b/java/jvpp-stats/io/fd/jvpp/stats/JVppStatsImpl.java index fdee289..2b30182 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/JVppStatsImpl.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/JVppStatsImpl.java @@ -82,6 +82,8 @@ public class JVppStatsImpl implements io.fd.jvpp.stats.JVppStats { private static native int interfaceStatisticsDump0() throws io.fd.jvpp.VppInvocationException; + private static native int interfaceNamesDump0() throws io.fd.jvpp.VppInvocationException; + private static native void close0(); @Override @@ -114,6 +116,17 @@ public class JVppStatsImpl implements io.fd.jvpp.stats.JVppStats { return result; } + @Override + public int interfaceNamesDump() throws VppInvocationException { + connection.checkActive(); + LOG.fine("Sending interfaceNamesDump event message"); + int result = interfaceNamesDump0(); + if (result < 0) { + throw new io.fd.jvpp.VppInvocationException("interfaceNamesDump", result); + } + return result; + } + @Override public void close() { close0(); diff --git a/java/jvpp-stats/io/fd/jvpp/stats/callback/InterfaceNamesDetailsCallback.java b/java/jvpp-stats/io/fd/jvpp/stats/callback/InterfaceNamesDetailsCallback.java new file mode 100644 index 0000000..56fd0f5 --- /dev/null +++ b/java/jvpp-stats/io/fd/jvpp/stats/callback/InterfaceNamesDetailsCallback.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019 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.jvpp.stats.callback; + +/** + *

Represents callback for plugin's api message. + */ +public interface InterfaceNamesDetailsCallback extends io.fd.jvpp.callback.JVppCallback { + + void onInterfaceNamesDetails(io.fd.jvpp.stats.dto.InterfaceNamesDetails reply); +} diff --git a/java/jvpp-stats/io/fd/jvpp/stats/callback/JVppStatsGlobalCallback.java b/java/jvpp-stats/io/fd/jvpp/stats/callback/JVppStatsGlobalCallback.java index 794a645..9562dab 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/callback/JVppStatsGlobalCallback.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/callback/JVppStatsGlobalCallback.java @@ -19,5 +19,6 @@ package io.fd.jvpp.stats.callback; /** * Global aggregated callback interface. */ -public interface JVppStatsGlobalCallback extends io.fd.jvpp.stats.callback.InterfaceStatisticsDetailsCallback { +public interface JVppStatsGlobalCallback extends io.fd.jvpp.stats.callback.InterfaceStatisticsDetailsCallback, + io.fd.jvpp.stats.callback.InterfaceNamesDetailsCallback { } diff --git a/java/jvpp-stats/io/fd/jvpp/stats/callfacade/CallbackJVppStatsFacadeCallback.java b/java/jvpp-stats/io/fd/jvpp/stats/callfacade/CallbackJVppStatsFacadeCallback.java index ec1feb2..b1f8d54 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/callfacade/CallbackJVppStatsFacadeCallback.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/callfacade/CallbackJVppStatsFacadeCallback.java @@ -64,4 +64,21 @@ public final class CallbackJVppStatsFacadeCallback implements io.fd.jvpp.stats.c callback.onInterfaceStatisticsDetails(reply); } } + + @Override + public void onInterfaceNamesDetails(final io.fd.jvpp.stats.dto.InterfaceNamesDetails reply) { + + io.fd.jvpp.stats.callback.InterfaceNamesDetailsCallback callback; + final int replyId = reply.context; + if (LOG.isLoggable(java.util.logging.Level.FINE)) { + LOG.fine(String.format("Received InterfaceNamesDetails event message: %s", reply)); + } + synchronized (requests) { + callback = (io.fd.jvpp.stats.callback.InterfaceNamesDetailsCallback) requests.remove(replyId); + } + + if (callback != null) { + callback.onInterfaceNamesDetails(reply); + } + } } diff --git a/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceName.java b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceName.java new file mode 100644 index 0000000..a50471b --- /dev/null +++ b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceName.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 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.jvpp.stats.dto; + +import java.util.Objects; + +public class InterfaceName { + + public int swIfIndex; + public String name; + + public InterfaceName(final int swIfIndex, final String name) { + this.swIfIndex = swIfIndex; + this.name = name; + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + final InterfaceName otherIfc = (InterfaceName) other; + return swIfIndex == otherIfc.swIfIndex && name.equals(otherIfc.name); + } + + @Override + public int hashCode() { + return Objects.hash(swIfIndex, name); + } + + @Override + public String toString() { + return "InterfaceName{" + + "swIfIndex=" + swIfIndex + + ", name=" + name + + '}'; + } +} diff --git a/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetails.java b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetails.java new file mode 100644 index 0000000..c437faf --- /dev/null +++ b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetails.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019 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.jvpp.stats.dto; + +/** + *

This class represents reply DTO for InterfaceNamesDetails. + */ +public final class InterfaceNamesDetails implements io.fd.jvpp.dto.JVppReply { + public int context; + public InterfaceName[] interfaceNames; + public int length; + + public InterfaceNamesDetails(int length, int context) { + this.context = context; + this.length = length; + this.interfaceNames = new InterfaceName[length]; + } + + @Override + @io.fd.jvpp.coverity.SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD") + public int hashCode() { + return java.util.Objects.hash(context, interfaceNames, length); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final InterfaceNamesDetails other = (InterfaceNamesDetails) o; + + if (!java.util.Objects.equals(this.context, other.context)) { + return false; + } + if (!java.util.Arrays.equals(this.interfaceNames, other.interfaceNames)) { + return false; + } + if (!java.util.Objects.equals(this.length, other.length)) { + return false; + } else { + return true; + } + } + + @Override + public String toString() { + return "InterfaceNamesDetails{" + + "context=" + context + + ", interfaceNames=" + java.util.Arrays.toString(interfaceNames) + + ", length=" + length + + '}'; + } +} diff --git a/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetailsReplyDump.java b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetailsReplyDump.java new file mode 100644 index 0000000..c1e1b1b --- /dev/null +++ b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDetailsReplyDump.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019 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.jvpp.stats.dto; + +/** + *

This class represents dump reply wrapper for InterfaceNamesDetails. + */ +public final class InterfaceNamesDetailsReplyDump + implements io.fd.jvpp.dto.JVppReplyDump { + + public InterfaceNamesDetails interfaceNamesDetails; + + @Override + @io.fd.jvpp.coverity.SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD") + public int hashCode() { + return java.util.Objects.hash(interfaceNamesDetails); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + final InterfaceNamesDetailsReplyDump + other = (InterfaceNamesDetailsReplyDump) o; + + return java.util.Objects.equals(this.interfaceNamesDetails, other.interfaceNamesDetails); + } + + @Override + public String toString() { + return "InterfaceNamesDetailsReplyDump{" + + "interfaceNamesDetails=" + interfaceNamesDetails + + '}'; + } +} diff --git a/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDump.java b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDump.java new file mode 100644 index 0000000..79125aa --- /dev/null +++ b/java/jvpp-stats/io/fd/jvpp/stats/dto/InterfaceNamesDump.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019 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.jvpp.stats.dto; + +/** + *

This class represents request DTO. + */ +public final class InterfaceNamesDump implements io.fd.jvpp.dto.JVppDump { + + @Override + @io.fd.jvpp.coverity.SuppressFBWarnings("UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD") + public int hashCode() { + return java.util.Objects.hash(); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + return true; + } + + @Override + public String toString() { + return "InterfaceNamesDump{}"; + } + + @Override + public int send(final io.fd.jvpp.JVpp jvpp) throws io.fd.jvpp.VppInvocationException { + return ((io.fd.jvpp.stats.JVppStats) jvpp).interfaceNamesDump(); + } +} diff --git a/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStats.java b/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStats.java index 288b556..9e0db46 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStats.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStats.java @@ -16,6 +16,7 @@ package io.fd.jvpp.stats.future; +import io.fd.jvpp.stats.dto.InterfaceNamesDetailsReplyDump; import io.fd.jvpp.stats.dto.InterfaceStatisticsDetailsReplyDump; /** @@ -25,4 +26,7 @@ public interface FutureJVppStats extends io.fd.jvpp.stats.future.FutureJVppInvok java.util.concurrent.CompletionStage interfaceStatisticsDump( io.fd.jvpp.stats.dto.InterfaceStatisticsDump request); + + java.util.concurrent.CompletionStage interfaceNamesDump( + io.fd.jvpp.stats.dto.InterfaceNamesDump request); } diff --git a/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacade.java b/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacade.java index 470a2fd..8e5e118 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacade.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacade.java @@ -17,7 +17,10 @@ package io.fd.jvpp.stats.future; import io.fd.jvpp.notification.EventRegistry; +import io.fd.jvpp.stats.dto.InterfaceNamesDetailsReplyDump; +import io.fd.jvpp.stats.dto.InterfaceNamesDump; import io.fd.jvpp.stats.dto.InterfaceStatisticsDetailsReplyDump; +import java.util.concurrent.CompletionStage; /** *

Implementation of FutureJVpp based on AbstractFutureJVppInvoker @@ -46,6 +49,11 @@ public class FutureJVppStatsFacade extends io.fd.jvpp.stats.future.AbstractFutur return send(request, new InterfaceStatisticsDetailsReplyDump()); } + @Override + public CompletionStage interfaceNamesDump(final InterfaceNamesDump request) { + return send(request, new InterfaceNamesDetailsReplyDump()); + } + @Override public EventRegistry getEventRegistry() { return null; diff --git a/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacadeCallback.java b/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacadeCallback.java index a215b89..1c9dfb5 100644 --- a/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacadeCallback.java +++ b/java/jvpp-stats/io/fd/jvpp/stats/future/FutureJVppStatsFacadeCallback.java @@ -16,6 +16,7 @@ package io.fd.jvpp.stats.future; +import io.fd.jvpp.stats.dto.InterfaceNamesDetailsReplyDump; import io.fd.jvpp.stats.dto.InterfaceStatisticsDetailsReplyDump; /** @@ -78,4 +79,31 @@ public final class FutureJVppStatsFacadeCallback implements io.fd.jvpp.stats.cal completableFuture.getReplyDump().interfaceStatisticsDetails = reply; } } + + @Override + @SuppressWarnings("unchecked") + public void onInterfaceNamesDetails(final io.fd.jvpp.stats.dto.InterfaceNamesDetails reply) { + io.fd.jvpp.stats.future.AbstractFutureJVppInvoker.CompletableDumpFuture + completableFuture; + final int replyId = reply.context; + if (LOG.isLoggable(java.util.logging.Level.FINE)) { + LOG.fine(String.format("Received InterfaceNamesDetails event message: %s", reply)); + } + synchronized (requests) { + completableFuture = + (io.fd.jvpp.stats.future.AbstractFutureJVppInvoker.CompletableDumpFuture) requests + .get(replyId); + + if (completableFuture == null) { + // reply received before writer created future, + // create new future, and put into map to notify sender that reply is already received, + // following details replies will add information to this future + completableFuture = + new io.fd.jvpp.stats.future.AbstractFutureJVppInvoker.CompletableDumpFuture<>(replyId, + new InterfaceNamesDetailsReplyDump()); + requests.put(replyId, completableFuture); + } + completableFuture.getReplyDump().interfaceNamesDetails = reply; + } + } } diff --git a/java/jvpp-stats/io/fd/jvpp/stats/test/FutureApiNamesTest.java b/java/jvpp-stats/io/fd/jvpp/stats/test/FutureApiNamesTest.java new file mode 100644 index 0000000..49c48d7 --- /dev/null +++ b/java/jvpp-stats/io/fd/jvpp/stats/test/FutureApiNamesTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 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.jvpp.stats.test; + + +import io.fd.jvpp.JVppRegistry; +import io.fd.jvpp.stats.JVppStatsImpl; +import io.fd.jvpp.stats.JVppStatsRegistryImpl; +import io.fd.jvpp.stats.dto.InterfaceNamesDetailsReplyDump; +import io.fd.jvpp.stats.dto.InterfaceNamesDump; +import io.fd.jvpp.stats.future.FutureJVppStatsFacade; +import java.util.concurrent.Future; +import java.util.logging.Logger; + +public class FutureApiNamesTest { + + private static final Logger LOG = Logger.getLogger(FutureApiNamesTest.class.getName()); + + public static void main(String[] args) throws Exception { + testCallbackApi(args); + } + + private static void testCallbackApi(String[] args) throws Exception { + LOG.info("Testing Java callback API for stats plugin"); + try (final JVppRegistry registry = new JVppStatsRegistryImpl("FutureApiTest"); + final FutureJVppStatsFacade jvpp = new FutureJVppStatsFacade(registry, new JVppStatsImpl())) { + LOG.info("Successfully connected to VPP"); + testinterfaceNamesDump(jvpp); + + LOG.info("Disconnecting..."); + } + } + + private static void testinterfaceNamesDump(FutureJVppStatsFacade jvpp) throws Exception { + LOG.info("Sending InterfaceNamesDump request..."); + final InterfaceNamesDump request = new InterfaceNamesDump(); + + final Future replyFuture = + jvpp.interfaceNamesDump(request).toCompletableFuture(); + final InterfaceNamesDetailsReplyDump reply = replyFuture.get(); + + if (reply == null || reply.interfaceNamesDetails == null) { + throw new IllegalStateException("Received null response for empty dump: " + reply); + } else { + LOG.info(String.format("Received interface names reply: %s \n", reply.interfaceNamesDetails)); + } + } +} -- cgit 1.2.3-korg