summaryrefslogtreecommitdiffstats
path: root/vpp-management
diff options
context:
space:
mode:
authorJan Srnicek <jsrnicek@cisco.com>2017-03-14 09:29:12 +0100
committerMarek Gradzki <mgradzki@cisco.com>2017-03-14 14:33:40 +0100
commit5ec31f19f7a74a884e2bef8e5238fdd4cfa2c4c2 (patch)
tree53a3542d6ea26cb9d6f4ab5d827a12b2d9543db9 /vpp-management
parent4616f0300655582153362a21910bd1f0b14937ae (diff)
HC2VPP-7 - Split vpp state/Cli RPC to separate module
Introduces VppManageModule containing - Vpp state attributes - CLI RPC support - Keep-alive Change-Id: I8907e57132cc9e57840aa3b9607fa131a77f767d Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'vpp-management')
-rw-r--r--vpp-management/api/asciidoc/Readme.adoc9
-rw-r--r--vpp-management/api/pom.xml32
-rw-r--r--vpp-management/api/src/main/yang/vpp-management.yang54
-rw-r--r--vpp-management/asciidoc/Readme.adoc3
-rw-r--r--vpp-management/impl/asciidoc/Readme.adoc15
-rw-r--r--vpp-management/impl/pom.xml95
-rw-r--r--vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementConfiguration.java32
-rw-r--r--vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementModule.java47
-rw-r--r--vpp-management/impl/src/main/java/io/fd/hc2vpp/management/rpc/CliInbandService.java62
-rw-r--r--vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/StateReaderFactory.java61
-rw-r--r--vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/VersionCustomizer.java82
-rw-r--r--vpp-management/impl/src/main/resources/honeycomb-minimal-resources/config/vpp-management.json3
-rw-r--r--vpp-management/impl/src/test/java/io/fd/hc2vpp/management/VppManagementModuleTest.java69
-rw-r--r--vpp-management/impl/src/test/java/io/fd/hc2vpp/management/rpc/CliInbandServiceTest.java52
-rw-r--r--vpp-management/impl/src/test/java/io/fd/hc2vpp/management/state/VppStateTest.java142
-rw-r--r--vpp-management/impl/src/test/resources/vpp-management.json3
-rw-r--r--vpp-management/pom.xml58
-rw-r--r--vpp-management/vpp_management_postman_collection.json106
18 files changed, 925 insertions, 0 deletions
diff --git a/vpp-management/api/asciidoc/Readme.adoc b/vpp-management/api/asciidoc/Readme.adoc
new file mode 100644
index 000000000..221faa60b
--- /dev/null
+++ b/vpp-management/api/asciidoc/Readme.adoc
@@ -0,0 +1,9 @@
+= vpp-management-api
+
+Overview of vpp-management-api
+
+Provides model for two major features
+
+* Management attributes of underlaying vpp instance(version,pid,...)
+* RPC support for invoking CLI commands
+
diff --git a/vpp-management/api/pom.xml b/vpp-management/api/pom.xml
new file mode 100644
index 000000000..8168257e2
--- /dev/null
+++ b/vpp-management/api/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>io.fd.honeycomb.common</groupId>
+ <artifactId>api-parent</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ </parent>
+
+ <groupId>io.fd.hc2vpp.management</groupId>
+ <artifactId>vpp-management-api</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+</project> \ No newline at end of file
diff --git a/vpp-management/api/src/main/yang/vpp-management.yang b/vpp-management/api/src/main/yang/vpp-management.yang
new file mode 100644
index 000000000..2582cbea4
--- /dev/null
+++ b/vpp-management/api/src/main/yang/vpp-management.yang
@@ -0,0 +1,54 @@
+module vpp-management {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:vpp:management";
+ prefix "vpp-m";
+
+ revision "2017-03-15" {
+ description
+ "This revision add support for
+ - Vpp state attributes read
+ - RPC cli support";
+ }
+
+ container vpp-state {
+ config false;
+
+ description
+ "VPP operational data";
+
+ container version {
+ leaf name {
+ type string;
+ }
+ leaf build-directory {
+ type string;
+ }
+ leaf build-date {
+ type string;
+ }
+ leaf branch {
+ type string;
+ }
+ leaf pid {
+ type uint32;
+ description
+ "PID of the vpp process";
+ }
+ description
+ "vlib version info";
+ }
+ }
+
+ rpc cli-inband {
+ input {
+ leaf cmd {
+ type string;
+ }
+ }
+ output {
+ leaf reply {
+ type string;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/vpp-management/asciidoc/Readme.adoc b/vpp-management/asciidoc/Readme.adoc
new file mode 100644
index 000000000..8fa4da830
--- /dev/null
+++ b/vpp-management/asciidoc/Readme.adoc
@@ -0,0 +1,3 @@
+= vpp-management-aggregator
+
+Overview of vpp-management-aggregator \ No newline at end of file
diff --git a/vpp-management/impl/asciidoc/Readme.adoc b/vpp-management/impl/asciidoc/Readme.adoc
new file mode 100644
index 000000000..c53e5db0d
--- /dev/null
+++ b/vpp-management/impl/asciidoc/Readme.adoc
@@ -0,0 +1,15 @@
+= vpp-management-impl
+
+Overview of vpp-management-impl
+
+Provides following features
+
+* Read support for VPP management attributes
+* Implementation of RPC support of CLI commands
+* Initialization of Keep-alive service
+
+Exposes following configuration
+
+*vpp-management.json*
+
+* keepalive-delay - delay period for keep-alive manager \ No newline at end of file
diff --git a/vpp-management/impl/pom.xml b/vpp-management/impl/pom.xml
new file mode 100644
index 000000000..da4d8ff12
--- /dev/null
+++ b/vpp-management/impl/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>vpp-impl-parent</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ <relativePath>../../vpp-common/vpp-impl-parent</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>io.fd.hc2vpp.management</groupId>
+ <artifactId>vpp-management-impl</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+
+ <dependencies>
+ <!-- Api -->
+ <dependency>
+ <groupId>io.fd.hc2vpp.management</groupId>
+ <artifactId>vpp-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>translate-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>rpc-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- DI -->
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-multibindings</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.jmob</groupId>
+ <artifactId>guice.conf</artifactId>
+ </dependency>
+
+ <!-- Translate -->
+ <dependency>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>vpp-translate-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.honeycomb</groupId>
+ <artifactId>translate-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- Test -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.fd.hc2vpp.common</groupId>
+ <artifactId>vpp-translate-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject.extensions</groupId>
+ <artifactId>guice-testlib</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementConfiguration.java b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementConfiguration.java
new file mode 100644
index 000000000..53872f16e
--- /dev/null
+++ b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementConfiguration.java
@@ -0,0 +1,32 @@
+/*
+ * 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.hc2vpp.management;
+
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+@BindConfig(value = "vpp-management", syntax = Syntax.JSON)
+public class VppManagementConfiguration {
+
+ @InjectConfig("keepalive-delay")
+ private int keepaliveDelay;
+
+ public int getKeepaliveDelay() {
+ return this.keepaliveDelay;
+ }
+}
diff --git a/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementModule.java b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementModule.java
new file mode 100644
index 000000000..508da64d0
--- /dev/null
+++ b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/VppManagementModule.java
@@ -0,0 +1,47 @@
+/*
+ * 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.hc2vpp.management;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.multibindings.Multibinder;
+import io.fd.hc2vpp.management.rpc.CliInbandService;
+import io.fd.hc2vpp.management.state.StateReaderFactory;
+import io.fd.honeycomb.rpc.RpcService;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+public class VppManagementModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ install(ConfigurationModule.create());
+ requestInjection(VppManagementConfiguration.class);
+
+ // Readers
+ final Multibinder<ReaderFactory> readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class);
+ readerFactoryBinder.addBinding().to(StateReaderFactory.class);
+
+ // Executor needed for keepalives
+ bind(ScheduledExecutorService.class).toInstance(Executors.newScheduledThreadPool(1));
+
+ // RPCs
+ final Multibinder<RpcService> rpcsBinder = Multibinder.newSetBinder(binder(), RpcService.class);
+ rpcsBinder.addBinding().to(CliInbandService.class);
+ }
+}
diff --git a/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/rpc/CliInbandService.java b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/rpc/CliInbandService.java
new file mode 100644
index 000000000..ab55abe3f
--- /dev/null
+++ b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/rpc/CliInbandService.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hc2vpp.management.rpc;
+
+import com.google.inject.Inject;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.rpc.RpcService;
+import io.fd.vpp.jvpp.core.dto.CliInband;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.CliInbandInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.CliInbandOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.CliInbandOutputBuilder;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class CliInbandService implements RpcService<CliInbandInput, CliInbandOutput>, JvppReplyConsumer {
+
+ private final FutureJVppCore jvpp;
+ private static final String localName = "cli-inband";
+ private static final QName name = QName.create(CliInbandInput.QNAME, localName);
+ private static final SchemaPath schemaPath = SchemaPath.ROOT.createChild(name);
+
+ @Inject
+ public CliInbandService(@Nonnull final FutureJVppCore jvpp) {
+ this.jvpp = jvpp;
+ }
+
+ @Override
+ @Nonnull
+ public CompletionStage<CliInbandOutput> invoke(@Nonnull final CliInbandInput input) {
+ final CliInband request = new CliInband();
+ request.cmd = input.getCmd().getBytes(StandardCharsets.UTF_8);
+ request.length = request.cmd.length;
+ return jvpp.cliInband(request)
+ .thenApply(
+ reply -> new CliInbandOutputBuilder().setReply(new String(reply.reply)).build()
+ );
+ }
+
+ @Nonnull
+ @Override
+ public SchemaPath getManagedNode() {
+ return schemaPath;
+ }
+}
diff --git a/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/StateReaderFactory.java b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/StateReaderFactory.java
new file mode 100644
index 000000000..541de30a1
--- /dev/null
+++ b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/StateReaderFactory.java
@@ -0,0 +1,61 @@
+/*
+ * 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.hc2vpp.management.state;
+
+import com.google.inject.Inject;
+import io.fd.hc2vpp.common.translate.util.ReadTimeoutException;
+import io.fd.hc2vpp.common.translate.util.VppStatusListener;
+import io.fd.hc2vpp.management.VppManagementConfiguration;
+import io.fd.honeycomb.translate.impl.read.GenericReader;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.concurrent.ScheduledExecutorService;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.VppState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.VppStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.vpp.state.Version;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class StateReaderFactory implements ReaderFactory {
+
+ @Inject
+ private FutureJVppCore vppApi;
+
+ @Inject
+ private ScheduledExecutorService keepaliveExecutor;
+
+ @Inject
+ private VppStatusListener vppStatusListener;
+
+ @Inject
+ private VppManagementConfiguration configuration;
+
+ @Override
+ public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+ // VppState(Structural)
+ final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
+ registry.addStructuralReader(vppStateId, VppStateBuilder.class);
+ // Version
+ // Wrap with keepalive reader to detect connection issues
+ // Relying on VersionCustomizer to provide a "timing out read"
+ registry.add(new KeepaliveReaderWrapper<>(
+ new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(vppApi)),
+ keepaliveExecutor, ReadTimeoutException.class, configuration.getKeepaliveDelay(), vppStatusListener));
+ }
+}
diff --git a/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/VersionCustomizer.java b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/VersionCustomizer.java
new file mode 100644
index 000000000..bfbabcb0c
--- /dev/null
+++ b/vpp-management/impl/src/main/java/io/fd/hc2vpp/management/state/VersionCustomizer.java
@@ -0,0 +1,82 @@
+/*
+ * 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.hc2vpp.management.state;
+
+import com.google.common.primitives.UnsignedInts;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.vpp.jvpp.core.dto.ShowVersion;
+import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import io.fd.vpp.jvpp.dto.ControlPing;
+import io.fd.vpp.jvpp.dto.ControlPingReply;
+import io.fd.vpp.jvpp.dto.JVppReply;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.VppStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.vpp.state.Version;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.vpp.state.VersionBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public final class VersionCustomizer
+ extends FutureJVppCustomizer
+ implements ReaderCustomizer<Version, VersionBuilder>, ByteDataTranslator, JvppReplyConsumer {
+
+ public VersionCustomizer(@Nonnull final FutureJVppCore futureJVppCore) {
+ super(futureJVppCore);
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final Version readValue) {
+ ((VppStateBuilder) parentBuilder).setVersion(readValue);
+ }
+
+ @Nonnull
+ @Override
+ public VersionBuilder getBuilder(@Nonnull InstanceIdentifier<Version> id) {
+ return new VersionBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Version> id, @Nonnull final VersionBuilder builder,
+ @Nonnull final ReadContext context) throws ReadFailedException {
+
+ // Execute with timeout
+ final CompletionStage<ShowVersionReply> showVersionFuture = getFutureJVpp().showVersion(new ShowVersion());
+ final ShowVersionReply reply = getReplyForRead(showVersionFuture.toCompletableFuture(), id);
+
+ builder.setBranch(toString(reply.version));
+ builder.setName(toString(reply.program));
+ builder.setBuildDate(toString(reply.buildDate));
+ builder.setBuildDirectory(toString(reply.buildDirectory));
+ builder.setPid(getPid(id));
+ }
+
+ private Long getPid(@Nonnull final InstanceIdentifier<Version> id) throws ReadFailedException {
+ final CompletionStage<JVppReply<ControlPing>> request = getFutureJVpp().send(new ControlPing());
+ final ControlPingReply reply = (ControlPingReply)getReplyForRead(request.toCompletableFuture(), id);
+ return UnsignedInts.toLong(reply.vpePid);
+ }
+
+
+}
diff --git a/vpp-management/impl/src/main/resources/honeycomb-minimal-resources/config/vpp-management.json b/vpp-management/impl/src/main/resources/honeycomb-minimal-resources/config/vpp-management.json
new file mode 100644
index 000000000..28b25b263
--- /dev/null
+++ b/vpp-management/impl/src/main/resources/honeycomb-minimal-resources/config/vpp-management.json
@@ -0,0 +1,3 @@
+{
+ "keepalive-delay":30
+} \ No newline at end of file
diff --git a/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/VppManagementModuleTest.java b/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/VppManagementModuleTest.java
new file mode 100644
index 000000000..eb2c3a933
--- /dev/null
+++ b/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/VppManagementModuleTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.hc2vpp.management;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.testing.fieldbinder.Bind;
+import com.google.inject.testing.fieldbinder.BoundFieldModule;
+import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class VppManagementModuleTest {
+
+ @Bind
+ @Mock
+ private FutureJVppCore futureJVppCore;
+
+ @Inject
+ private VppManagementConfiguration configuration;
+
+ @Inject
+ private Set<ReaderFactory> readerFactories = new HashSet<>();
+
+ @Before
+ public void setUp() {
+ initMocks(this);
+ Guice.createInjector(new VppManagementModule(), BoundFieldModule.of(this)).injectMembers(this);
+ }
+
+ @Test
+ public void testReaderFactories() throws Exception {
+ assertFalse(readerFactories.isEmpty());
+
+ // Test registration process (all dependencies present, topological order of readers does exist, etc.)
+ final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder();
+ readerFactories.stream().forEach(factory -> factory.init(registryBuilder));
+ assertNotNull(registryBuilder.build());
+ }
+
+ @Test
+ public void testConfiguration() {
+ assertEquals(30, configuration.getKeepaliveDelay());
+ }
+} \ No newline at end of file
diff --git a/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/rpc/CliInbandServiceTest.java b/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/rpc/CliInbandServiceTest.java
new file mode 100644
index 000000000..dcf0a0186
--- /dev/null
+++ b/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/rpc/CliInbandServiceTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.hc2vpp.management.rpc;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import io.fd.hc2vpp.common.test.util.FutureProducer;
+import io.fd.vpp.jvpp.core.dto.CliInbandReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.CliInbandInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.CliInbandInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.CliInbandOutput;
+
+public class CliInbandServiceTest implements FutureProducer {
+
+ @Mock
+ private FutureJVppCore api;
+
+ @Test
+ public void testInvoke() throws Exception {
+ initMocks(this);
+ final String replyString = "CLI output";
+
+ final CliInbandService service = new CliInbandService(api);
+ final CliInbandReply reply = new CliInbandReply();
+ reply.reply = replyString.getBytes();
+ when(api.cliInband(any())).thenReturn(future(reply));
+
+ final CliInbandInput request = new CliInbandInputBuilder().setCmd("cmd").build();
+ final CliInbandOutput response = service.invoke(request).toCompletableFuture().get();
+ assertEquals(replyString, response.getReply());
+ }
+} \ No newline at end of file
diff --git a/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/state/VppStateTest.java b/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/state/VppStateTest.java
new file mode 100644
index 000000000..81db88511
--- /dev/null
+++ b/vpp-management/impl/src/test/java/io/fd/hc2vpp/management/state/VppStateTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.hc2vpp.management.state;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import io.fd.hc2vpp.common.test.util.FutureProducer;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.impl.read.GenericReader;
+import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.registry.ReaderRegistry;
+import io.fd.vpp.jvpp.core.dto.ShowVersion;
+import io.fd.vpp.jvpp.core.dto.ShowVersionReply;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import io.fd.vpp.jvpp.dto.ControlPing;
+import io.fd.vpp.jvpp.dto.ControlPingReply;
+import javax.annotation.Nonnull;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.VppState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.VppStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.vpp.state.Version;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.management.rev170315.vpp.state.VersionBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class VppStateTest implements FutureProducer {
+
+ @Mock
+ private FutureJVppCore api;
+ @Mock
+ private ReadContext ctx;
+ @Mock
+ private MappingContext mappingContext;
+
+ private ReaderRegistry readerRegistry;
+
+ /**
+ * Create root VppState reader with all its children wired.
+ */
+ private static ReaderRegistry getVppStateReader(@Nonnull final FutureJVppCore jVpp) {
+ final CompositeReaderRegistryBuilder registry = new CompositeReaderRegistryBuilder();
+
+ // VppState(Structural)
+ final InstanceIdentifier<VppState> vppStateId = InstanceIdentifier.create(VppState.class);
+ registry.addStructuralReader(vppStateId, VppStateBuilder.class);
+ // Version
+ registry.add(new GenericReader<>(vppStateId.child(Version.class), new VersionCustomizer(jVpp)));
+ return registry.build();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ initMocks(this);
+ final ModificationCache cache = new ModificationCache();
+ doReturn(cache).when(ctx).getModificationCache();
+ doReturn(mappingContext).when(ctx).getMappingContext();
+
+
+ readerRegistry = getVppStateReader(api);
+ }
+
+ private static Version getVersion() {
+ return new VersionBuilder()
+ .setName("test")
+ .setBuildDirectory("1")
+ .setBranch("2")
+ .setBuildDate("3")
+ .setPid(0L)
+ .build();
+ }
+
+ private void whenShowVersionThenReturn(final Version version) {
+ final ShowVersionReply reply = new ShowVersionReply();
+ reply.buildDate = version.getBuildDate().getBytes();
+ reply.program = version.getName().getBytes();
+ reply.version = version.getBranch().getBytes();
+ reply.buildDirectory = version.getBuildDirectory().getBytes();
+ when(api.showVersion(ArgumentMatchers.any(ShowVersion.class))).thenReturn(future(reply));
+ // Version Customizer uses ControlPing to obtain PID
+ when(api.send(ArgumentMatchers.any(ControlPing.class))).thenReturn(future(new ControlPingReply()));
+ }
+
+ @Test
+ public void testReadAll() throws Exception {
+ final Version version = getVersion();
+ whenShowVersionThenReturn(version);
+
+ final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects =
+ readerRegistry.readAll(ctx);
+ assertEquals(dataObjects.size(), 1);
+ final VppState dataObject =
+ (VppState) Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet())));
+ assertEquals(version, dataObject.getVersion());
+ }
+
+ @Test
+ public void testReadSpecific() throws Exception {
+ final Version version = getVersion();
+ whenShowVersionThenReturn(version);
+
+ final Optional<? extends DataObject> read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx);
+ assertTrue(read.isPresent());
+ assertEquals(version, ((VppState) read.get()).getVersion());
+ }
+
+ @Test
+ public void testReadVersion() throws Exception {
+ whenShowVersionThenReturn(getVersion());
+ VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
+
+ Optional<? extends DataObject> read =
+ readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class), ctx);
+ assertTrue(read.isPresent());
+ assertEquals(readRoot.getVersion(), read.get());
+ }
+} \ No newline at end of file
diff --git a/vpp-management/impl/src/test/resources/vpp-management.json b/vpp-management/impl/src/test/resources/vpp-management.json
new file mode 100644
index 000000000..28b25b263
--- /dev/null
+++ b/vpp-management/impl/src/test/resources/vpp-management.json
@@ -0,0 +1,3 @@
+{
+ "keepalive-delay":30
+} \ No newline at end of file
diff --git a/vpp-management/pom.xml b/vpp-management/pom.xml
new file mode 100644
index 000000000..a87af1d9d
--- /dev/null
+++ b/vpp-management/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>io.fd.honeycomb.common</groupId>
+ <artifactId>honeycomb-parent</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+ </parent>
+
+ <packaging>pom</packaging>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>io.fd.hc2vpp.management</groupId>
+ <artifactId>vpp-management-aggregator</artifactId>
+ <version>1.17.04-SNAPSHOT</version>
+
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ </modules>
+
+ <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build -->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/vpp-management/vpp_management_postman_collection.json b/vpp-management/vpp_management_postman_collection.json
new file mode 100644
index 000000000..591862dd5
--- /dev/null
+++ b/vpp-management/vpp_management_postman_collection.json
@@ -0,0 +1,106 @@
+{
+ "id": "b638a073-6954-5c89-320a-7105437dae94",
+ "name": "Vpp management Collection",
+ "description": "",
+ "order": [
+ "1bfd69f7-e187-beb0-447c-0074aa636045"
+ ],
+ "folders": [
+ {
+ "id": "299be85f-5ada-34f7-bd80-9fbc4e5b200a",
+ "name": "RPCs",
+ "description": "",
+ "order": [
+ "1c552a48-498c-f2e8-8dee-2d5b67120a3a",
+ "2df7f806-dfb3-bf4f-9cab-0c9863ed4486",
+ "d4f87db0-06e5-b309-8918-d1c29f59fab1"
+ ],
+ "owner": "658985"
+ }
+ ],
+ "timestamp": 1489148746054,
+ "owner": "658985",
+ "public": false,
+ "requests": [
+ {
+ "id": "1bfd69f7-e187-beb0-447c-0074aa636045",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "url": "http://localhost:8183/restconf/operational/vpp-management:vpp-state",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "GET",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1489149850732,
+ "name": "Read vpp-state - oper",
+ "description": "",
+ "collectionId": "b638a073-6954-5c89-320a-7105437dae94",
+ "responses": [],
+ "rawModeData": "{\r\n \r\n \"interface\": [\r\n {\r\n \"name\": \"testInterface\",\r\n \"description\": \"for testing purposes\",\r\n \"type\": \"iana-if-type:ethernetCsmacd\",\r\n \"enabled\": \"true\",\r\n \"link-up-down-trap-enable\": \"enabled\",\r\n \"ietf-ip:ipv4\": {\r\n \"enabled\": \"true\",\r\n \"mtu\": \"1500\",\r\n \"address\": [\r\n {\r\n \"ip\": \"1.2.3.0\",\r\n \"netmask\": \"255.255.255.0\"\r\n }\r\n ]\r\n }\r\n }\r\n ]\r\n \r\n}"
+ },
+ {
+ "id": "1c552a48-498c-f2e8-8dee-2d5b67120a3a",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "url": "http://localhost:8183/restconf/operations/vpp-management:cli-inband",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1489149921151,
+ "name": "show version",
+ "description": "The cli-inband rpc provides support for CLI commands.\nHere is equivalent of show version.",
+ "collectionId": "b638a073-6954-5c89-320a-7105437dae94",
+ "responses": [],
+ "rawModeData": "{\n \"input\" :\n {\n \"cmd\" : \"show version\"\n }\n}"
+ },
+ {
+ "id": "2df7f806-dfb3-bf4f-9cab-0c9863ed4486",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "url": "http://localhost:8183/restconf/operations/vpp-management:cli-inband",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1489149929797,
+ "name": "show interfaces",
+ "description": "The cli-inband rpc provides support for CLI commands.\nHere is equivalent of show int.",
+ "collectionId": "b638a073-6954-5c89-320a-7105437dae94",
+ "responses": [],
+ "rawModeData": "{\n \"input\" :\n {\n \"cmd\" : \"show int\"\n }\n}"
+ },
+ {
+ "id": "d4f87db0-06e5-b309-8918-d1c29f59fab1",
+ "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n",
+ "url": "http://localhost:8183/restconf/operations/vpp-management:cli-inband",
+ "preRequestScript": "",
+ "pathVariables": {},
+ "method": "POST",
+ "data": [],
+ "dataMode": "raw",
+ "version": 2,
+ "tests": "",
+ "currentHelper": "normal",
+ "helperAttributes": {},
+ "time": 1489149940101,
+ "name": "create loopback interface",
+ "description": "The cli-inband rpc provides support for CLI commands.\nHere is equivalent of create loopback interface",
+ "collectionId": "b638a073-6954-5c89-320a-7105437dae94",
+ "responses": [],
+ "rawModeData": "{\n \"input\" :\n {\n \"cmd\" : \"create loopback interface\"\n }\n}"
+ }
+ ]
+} \ No newline at end of file