From 6c3f614edb18bdb8cc6e7b87627f240d97a258c3 Mon Sep 17 00:00:00 2001 From: Jan Srnicek Date: Thu, 13 Oct 2016 13:56:47 +0200 Subject: HONEYCOMB-207 : Configurable modules list for distributions Export list of modules for built distribution on compile time according to distribution.modules property to ***module-config.txt Load aggregated set of modules on start from all descriptors in /modules folder Change-Id: Icdeb23536aee3a243a221d3f2ec5f340d387764e Signed-off-by: Jan Srnicek --- common/minimal-distribution-parent/pom.xml | 52 ++++++- infra/minimal-distribution/pom.xml | 27 ++++ .../infra/distro/ActiveModuleProvider.java | 154 +++++++++++++++++++++ .../java/io/fd/honeycomb/infra/distro/Main.java | 36 ++--- .../infra/distro/ActiveModuleProviderTest.java | 91 ++++++++++++ .../infra/distro/BaseMinimalDistributionTest.java | 26 +++- .../java/io/fd/honeycomb/infra/distro/Modules.java | 44 ++++++ .../test/resources/modules/module-config-one.txt | 4 + .../test/resources/modules/module-config-two.txt | 1 + .../io/fd/honeycomb/vppnsh/impl/VppNshModule.java | 24 ---- .../vppnsh/impl/cfgattrs/VppNshConfiguration.java | 41 ------ .../honeycomb-minimal-resources/config/vppnsh.json | 3 - samples/minimal-distribution/pom.xml | 5 +- .../java/io/fd/honeycomb/samples/distro/Main.java | 33 ----- .../minimal-distribution/asciidoc/Readme.adoc | 3 - vpp-common/minimal-distribution/pom.xml | 116 ---------------- .../vpp/distro/ContextsReaderFactoryProvider.java | 40 ------ .../fd/honeycomb/vpp/distro/JVppCoreProvider.java | 61 -------- .../honeycomb/vpp/distro/JVppRegistryProvider.java | 72 ---------- .../main/java/io/fd/honeycomb/vpp/distro/Main.java | 32 ----- .../fd/honeycomb/vpp/distro/VppCommonModule.java | 44 ------ .../honeycomb/vpp/distro/VppConfigAttributes.java | 28 ---- .../honeycomb-minimal-resources/config/jvpp.json | 3 - .../honeycomb/vpp/distro/VppCommonModuleTest.java | 53 ------- .../src/test/resources/jvpp.json | 3 - vpp-common/pom.xml | 2 +- .../vpp-common-integration/asciidoc/Readme.adoc | 3 + vpp-common/vpp-common-integration/pom.xml | 116 ++++++++++++++++ .../integration/ContextsReaderFactoryProvider.java | 40 ++++++ .../vpp/common/integration/JVppCoreProvider.java | 61 ++++++++ .../common/integration/JVppRegistryProvider.java | 72 ++++++++++ .../vpp/common/integration/VppCommonModule.java | 44 ++++++ .../common/integration/VppConfigAttributes.java | 28 ++++ .../honeycomb-minimal-resources/config/jvpp.json | 3 + .../common/integration/VppCommonModuleTest.java | 53 +++++++ .../src/test/resources/jvpp.json | 3 + vpp-integration/minimal-distribution/pom.xml | 16 ++- .../fd/honeycomb/vpp/integration/distro/Main.java | 40 ------ 38 files changed, 848 insertions(+), 629 deletions(-) create mode 100644 infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ActiveModuleProvider.java create mode 100644 infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/ActiveModuleProviderTest.java create mode 100644 infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/Modules.java create mode 100644 infra/minimal-distribution/src/test/resources/modules/module-config-one.txt create mode 100644 infra/minimal-distribution/src/test/resources/modules/module-config-two.txt delete mode 100755 nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/cfgattrs/VppNshConfiguration.java delete mode 100644 nsh/impl/src/main/resources/honeycomb-minimal-resources/config/vppnsh.json delete mode 100644 samples/minimal-distribution/src/main/java/io/fd/honeycomb/samples/distro/Main.java delete mode 100644 vpp-common/minimal-distribution/asciidoc/Readme.adoc delete mode 100644 vpp-common/minimal-distribution/pom.xml delete mode 100644 vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/ContextsReaderFactoryProvider.java delete mode 100644 vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppCoreProvider.java delete mode 100644 vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppRegistryProvider.java delete mode 100644 vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/Main.java delete mode 100644 vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppCommonModule.java delete mode 100644 vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppConfigAttributes.java delete mode 100644 vpp-common/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/jvpp.json delete mode 100644 vpp-common/minimal-distribution/src/test/java/io/fd/honeycomb/vpp/distro/VppCommonModuleTest.java delete mode 100644 vpp-common/minimal-distribution/src/test/resources/jvpp.json create mode 100644 vpp-common/vpp-common-integration/asciidoc/Readme.adoc create mode 100644 vpp-common/vpp-common-integration/pom.xml create mode 100644 vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/ContextsReaderFactoryProvider.java create mode 100644 vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppCoreProvider.java create mode 100644 vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppRegistryProvider.java create mode 100644 vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppCommonModule.java create mode 100644 vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppConfigAttributes.java create mode 100644 vpp-common/vpp-common-integration/src/main/resources/honeycomb-minimal-resources/config/jvpp.json create mode 100644 vpp-common/vpp-common-integration/src/test/java/io/fd/honeycomb/vpp/common/integration/VppCommonModuleTest.java create mode 100644 vpp-common/vpp-common-integration/src/test/resources/jvpp.json delete mode 100644 vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java diff --git a/common/minimal-distribution-parent/pom.xml b/common/minimal-distribution-parent/pom.xml index b003231c3..eb68991c4 100644 --- a/common/minimal-distribution-parent/pom.xml +++ b/common/minimal-distribution-parent/pom.xml @@ -60,6 +60,12 @@ done http://stackoverflow.com/questions/137212/how-to-solve-performance-problem-with-java-securerandom --> /dev/./urandom + // This distribution does not define any own modules. +// In order to do so either distribution.modules property must be defined in distribution pom.xml, +// containing list of desired modules to start, or this file can be directly edited with same effect. +// +// Note : Modules should be referenced by full class name, for ex.: io.fd.test.SampleModule, and separated with comma. + @@ -127,7 +133,7 @@ done true - config/ cert/ + config/ cert/ modules/ @@ -167,11 +173,13 @@ done + org.codehaus.gmaven groovy-maven-plugin + start-scripts-generation package execute @@ -210,6 +218,48 @@ done + + distribution-module-assembly + + prepare-package + + execute + + + import java.nio.file.Paths + import java.nio.file.Files + + // module configuration file extraction + // builds project name from group,artifact and version to prevent overwriting + // while building multiple distribution project + def artifact = project.getArtifact() + def projectName = "${artifact.getGroupId()}_${artifact.getArtifactId()}_${artifact.getVersion()}".replace(".","-") + log.info "Generating list of modules started by distribution ${projectName}" + + def activeModules = properties.getProperty("distribution.modules", "") + .tokenize(",") + .collect { module -> module.trim() } + + log.info "Project ${projectName} : Found modules ${activeModules}" + //creates folder modules + + def outputPath = Paths.get(project.build.outputDirectory, "honeycomb-minimal-resources", "modules") + //creates module folder + outputPath.toFile().mkdirs() + + def outputFile = Paths.get(outputPath.toString(), "${projectName}_module-config.txt").toFile() + outputFile.createNewFile(); + log.info("Writing module configuration for distribution ${projectName} to ${outputPath}") + + if (activeModules.isEmpty()) { + outputFile.text = properties.getProperty("no.modules.defined.message") + } else { + outputFile.text = activeModules.join(System.lineSeparator) + } + + + diff --git a/infra/minimal-distribution/pom.xml b/infra/minimal-distribution/pom.xml index 6e935b09b..d727788a0 100644 --- a/infra/minimal-distribution/pom.xml +++ b/infra/minimal-distribution/pom.xml @@ -30,6 +30,17 @@ io.fd.honeycomb.infra.distro.Main + + io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule, + io.fd.honeycomb.infra.distro.schema.SchemaModule, + io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule, + io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule, + io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule, + io.fd.honeycomb.infra.distro.netconf.NetconfModule, + io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule, + io.fd.honeycomb.infra.distro.restconf.RestconfModule, + io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule + @@ -144,6 +155,12 @@ ${project.version} + + + com.google.guava + guava + + junit junit @@ -161,5 +178,15 @@ 0.1.54 test + + org.hamcrest + hamcrest-all + test + + + org.mockito + mockito-core + test + diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ActiveModuleProvider.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ActiveModuleProvider.java new file mode 100644 index 000000000..03c56969d --- /dev/null +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/ActiveModuleProvider.java @@ -0,0 +1,154 @@ +/* + * 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.honeycomb.infra.distro; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Module; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides list of active modules for distribution + */ +public class ActiveModuleProvider { + + public static final String STANDARD_MODULES_RELATIVE_PATH = "../modules/"; + private static final Logger LOG = LoggerFactory.getLogger(ActiveModuleProvider.class); + + /** + * Provide unique set of active modules filtered from provided resources + */ + public static Set loadActiveModules(@Nonnull final List moduleNames) { + final ClassLoader classLoader = ActiveModuleProvider.class.getClassLoader(); + LOG.info("Reading active modules configuration for distribution"); + + // process resources to resource modules + return moduleNames.stream() + .map(String::trim) + .filter(trimmedLine -> trimmedLine.length() != 0) + // filter out commented lines + .filter(nonEmptyLine -> !nonEmptyLine.startsWith("//")) + // filter duplicates + .distinct() + .map(validLine -> nameToClass(validLine, classLoader)) + // filters out classes that are not modules + .filter(ActiveModuleProvider::filterNonModules) + .map(ActiveModuleProvider::classToInstance) + .collect(Collectors.toSet()); + } + + /** + * Aggregate all resources from provided relative path into a {@code List} + */ + public static List aggregateResources(final String relativePath, final ClassLoader classLoader) { + try { + return Collections.list(classLoader.getResources(relativePath)).stream() + .map(ActiveModuleProvider::toURI) + .flatMap(ActiveModuleProvider::folderToFile) + .map(File::toURI) + .map(Paths::get) + // readAll lines and add them to iteration + .flatMap(ActiveModuleProvider::readLines) + .collect(Collectors.toList()); + } catch (IOException e) { + LOG.error("Unable to load resources from relative path {}", relativePath, e); + throw new IllegalStateException("Unable to load resources from relative path " + relativePath, e); + } + } + + private static Stream folderToFile(final URI uri) { + final File[] files = new File(uri).listFiles(File::isFile); + + return files != null + ? ImmutableList.copyOf(files).stream() + : Collections.emptyList().stream(); + } + + private static boolean filterNonModules(final Class clazz) { + final boolean isModule = Module.class.isAssignableFrom(clazz); + if (!isModule) { + LOG.warn("Class {} is provided in modules configuration, but is not a Module and will be ignored", clazz); + } + return isModule; + } + + /** + * Read lines from {@code Path} + */ + private static Stream readLines(final Path path) { + try { + return Files.readAllLines(path).stream(); + } catch (IOException e) { + LOG.error("Unable to read content of {}", path, e); + throw new IllegalStateException("Unable to read content of " + path, e); + } + } + + /** + * Converts {@code URL} to {@code URI} + */ + private static URI toURI(final URL url) { + try { + return url.toURI(); + } catch (URISyntaxException e) { + LOG.error("Unable to convert {} to uri", url); + throw new IllegalStateException("Unable to convert " + url + " to uri", e); + } + } + + /** + * Loads class by provided name + */ + private static Class nameToClass(final String name, + final ClassLoader classLoader) { + try { + LOG.info("Loading module class {}", name); + return classLoader.loadClass(name); + } catch (ClassNotFoundException e) { + LOG.error("Unable to convert {} to class, make sure you've provided sources to classpath", name); + throw new IllegalStateException( + "Unable to convert " + name + " to class, make sure you've provided sources to classpath", e); + } + } + + /** + * Creates instance of module class + */ + private static Module classToInstance(final Class moduleClass) { + try { + LOG.info("Creating instance for module {}", moduleClass); + return Module.class.cast(moduleClass.newInstance()); + } catch (InstantiationException | IllegalAccessException e) { + LOG.error("Unable to create instance for class {}", moduleClass, e); + throw new IllegalStateException("Unable to create instance for class" + moduleClass, e); + } + } +} diff --git a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java index d3a562d3a..3c62382c2 100644 --- a/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java +++ b/infra/minimal-distribution/src/main/java/io/fd/honeycomb/infra/distro/Main.java @@ -16,8 +16,11 @@ package io.fd.honeycomb.infra.distro; +import static io.fd.honeycomb.infra.distro.ActiveModuleProvider.STANDARD_MODULES_RELATIVE_PATH; +import static io.fd.honeycomb.infra.distro.ActiveModuleProvider.aggregateResources; +import static io.fd.honeycomb.infra.distro.ActiveModuleProvider.loadActiveModules; + import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; import com.google.inject.ConfigurationException; import com.google.inject.CreationException; import com.google.inject.Guice; @@ -28,20 +31,14 @@ import com.google.inject.ProvisionException; import com.google.inject.name.Names; import io.fd.honeycomb.data.init.DataTreeInitializer; import io.fd.honeycomb.data.init.InitializerRegistry; -import io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule; import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration; -import io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule; -import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule; import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule; import io.fd.honeycomb.infra.distro.netconf.HoneycombNotification2NetconfProvider; import io.fd.honeycomb.infra.distro.netconf.NetconfModule; -import io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule; import io.fd.honeycomb.infra.distro.netconf.NetconfSshServerProvider; import io.fd.honeycomb.infra.distro.netconf.NetconfTcpServerProvider; import io.fd.honeycomb.infra.distro.restconf.RestconfModule; -import io.fd.honeycomb.infra.distro.schema.SchemaModule; -import io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule; -import java.util.List; +import java.util.Set; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory; @@ -53,29 +50,18 @@ public final class Main { private static final Logger LOG = LoggerFactory.getLogger(Main.class); - public static final List BASE_MODULES = ImmutableList.of( - // Infra - new YangBindingProviderModule(), - new SchemaModule(), - new ConfigAndOperationalPipelineModule(), - new ContextPipelineModule(), - new InitializerPipelineModule(), - new NetconfModule(), - new NetconfReadersModule(), - new RestconfModule(), - // Json config attributes - new CfgAttrsModule()); - - private Main() {} + private Main() { + } public static void main(String[] args) { - init(BASE_MODULES); + final ClassLoader classLoader = Main.class.getClassLoader(); + init(loadActiveModules(aggregateResources(STANDARD_MODULES_RELATIVE_PATH, classLoader))); } /** - * Initialize the Honeycomb infrastructure + all wired plugins. + * Initialize the Honeycomb with provided modules */ - public static Injector init(final List modules) { + public static Injector init(final Set modules) { try { LOG.info("Starting honeycomb"); Injector injector = Guice.createInjector(modules); diff --git a/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/ActiveModuleProviderTest.java b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/ActiveModuleProviderTest.java new file mode 100644 index 000000000..bdadc5bd8 --- /dev/null +++ b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/ActiveModuleProviderTest.java @@ -0,0 +1,91 @@ +/* + * 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.honeycomb.infra.distro; + + +import static com.google.common.collect.ImmutableList.of; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.isA; +import static org.hamcrest.core.Is.is; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Module; +import java.util.List; +import java.util.Set; +import org.junit.Test; + +public class ActiveModuleProviderTest { + + @Test + public void testLoadActiveModulesSuccessfull() { + final ImmutableList rawResources = of( + "// this should be skipped", + "// io.fd.honeycomb.infra.distro.Modules$ChildModule1", + " io.fd.honeycomb.infra.distro.Modules$ChildModule2", + "io.fd.honeycomb.infra.distro.Modules$ChildModule3 ", + "io.fd.honeycomb.infra.distro.Modules$ChildModule3", + "io.fd.honeycomb.infra.distro.Modules$NonModule" + ); + + final Set activeModules = ActiveModuleProvider.loadActiveModules(rawResources); + + // first and second line should be ignored due to comment + // second,third,and fourth are valid,but should reduce module count to 2,because of duplicity + // last one does is not ancestor of Module, so it should be ignored/skipped + assertThat(activeModules, hasSize(2)); + //hasItems or containsInAnyOrder does not have/is deprecated in variant with matcher + assertThat(activeModules, hasItem(isA(io.fd.honeycomb.infra.distro.Modules.ChildModule2.class))); + assertThat(activeModules, hasItem(isA(io.fd.honeycomb.infra.distro.Modules.ChildModule3.class))); + } + + @Test(expected = IllegalStateException.class) + public void testLoadActiveModulesFailed() { + final ImmutableList rawResources = of( + "// this should be skipped", + "// io.fd.honeycomb.infra.distro.Modules$ChildModule1", + " io.fd.honeycomb.infra.distro.Modules$ChildModule2", + "### io.fd.honeycomb.infra.distro.Modules$ChildModule3 ",// it should fail because of this + "io.fd.honeycomb.infra.distro.Modules$ChildModule3", + "io.fd.honeycomb.infra.distro.Modules$NonModule" + ); + + ActiveModuleProvider.loadActiveModules(rawResources); + } + + @Test + public void testAggregateResourcesNonEmpty() { + final List aggregatedResources = + ActiveModuleProvider.aggregateResources("./modules", this.getClass().getClassLoader()); + assertThat(aggregatedResources, hasSize(5)); + assertThat(aggregatedResources, hasItems(" Non-commented non-trimmed", + "//Commented", + "// Commented non-trimmed", + "Not commented", + "// Line from second file")); + } + + @Test + public void testAggregateResourcesEmpty() { + assertThat(ActiveModuleProvider.aggregateResources("/non-existing-folder", this.getClass().getClassLoader()), + is(empty())); + } + +} diff --git a/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java index 61042868f..8a8ddc3ef 100644 --- a/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java +++ b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java @@ -16,22 +16,35 @@ package io.fd.honeycomb.infra.distro; +import static com.google.common.collect.ImmutableSet.of; import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import com.google.common.base.Charsets; import com.google.common.io.ByteStreams; +import com.google.inject.Module; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSubsystem; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; +import io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule; +import io.fd.honeycomb.infra.distro.data.ConfigAndOperationalPipelineModule; +import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule; +import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule; +import io.fd.honeycomb.infra.distro.netconf.NetconfModule; +import io.fd.honeycomb.infra.distro.netconf.NetconfReadersModule; +import io.fd.honeycomb.infra.distro.restconf.RestconfModule; +import io.fd.honeycomb.infra.distro.schema.SchemaModule; +import io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule; import java.io.IOException; import java.io.InputStream; import java.net.Socket; +import java.util.List; import java.util.Properties; +import java.util.Set; import javax.net.ssl.SSLContext; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; @@ -57,6 +70,17 @@ public class BaseMinimalDistributionTest { private static final String NETCONF_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0"; private static final int NETCONF_HELLO_WAIT = 2500; + public static final Set BASE_MODULES = of( + new YangBindingProviderModule(), + new SchemaModule(), + new ConfigAndOperationalPipelineModule(), + new ContextPipelineModule(), + new InitializerPipelineModule(), + new NetconfModule(), + new NetconfReadersModule(), + new RestconfModule(), + new CfgAttrsModule()); + @Before public void setUp() throws Exception { SSLContext sslcontext = SSLContexts.custom() @@ -76,7 +100,7 @@ public class BaseMinimalDistributionTest { */ @Test(timeout = 60000) public void test() throws Exception { - Main.init(Main.BASE_MODULES); + Main.init(BASE_MODULES); LOG.info("Testing Honeycomb base distribution"); LOG.info("Testing NETCONF TCP"); diff --git a/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/Modules.java b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/Modules.java new file mode 100644 index 000000000..e30fb87ca --- /dev/null +++ b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/Modules.java @@ -0,0 +1,44 @@ +/* + * 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.honeycomb.infra.distro; + +import com.google.inject.AbstractModule; +import com.google.inject.Binder; +import com.google.inject.Module; + +public class Modules { + + public static class ChildModule1 implements Module { + @Override + public void configure(final Binder binder) { + } + } + + public static class ChildModule2 implements Module { + @Override + public void configure(final Binder binder) { + } + } + + public static class ChildModule3 extends AbstractModule { + @Override + protected void configure() { + } + } + + public static class NonModule{} +} diff --git a/infra/minimal-distribution/src/test/resources/modules/module-config-one.txt b/infra/minimal-distribution/src/test/resources/modules/module-config-one.txt new file mode 100644 index 000000000..8d48a3c9d --- /dev/null +++ b/infra/minimal-distribution/src/test/resources/modules/module-config-one.txt @@ -0,0 +1,4 @@ +//Commented +// Commented non-trimmed +Not commented + Non-commented non-trimmed \ No newline at end of file diff --git a/infra/minimal-distribution/src/test/resources/modules/module-config-two.txt b/infra/minimal-distribution/src/test/resources/modules/module-config-two.txt new file mode 100644 index 000000000..ef11829e9 --- /dev/null +++ b/infra/minimal-distribution/src/test/resources/modules/module-config-two.txt @@ -0,0 +1 @@ +// Line from second file \ No newline at end of file diff --git a/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/VppNshModule.java b/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/VppNshModule.java index 156646628..e7d9d1535 100755 --- a/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/VppNshModule.java +++ b/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/VppNshModule.java @@ -17,8 +17,6 @@ package io.fd.honeycomb.vppnsh.impl; import com.google.inject.AbstractModule; -import com.google.inject.Guice; -import com.google.inject.Injector; import com.google.inject.Singleton; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; @@ -26,12 +24,10 @@ import io.fd.honeycomb.data.init.DataTreeInitializer; import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.translate.write.WriterFactory; -import io.fd.honeycomb.vppnsh.impl.cfgattrs.VppNshConfiguration; import io.fd.honeycomb.vppnsh.impl.config.VppNshWriterFactory; import io.fd.honeycomb.vppnsh.impl.init.VppNshInitializer; import io.fd.honeycomb.vppnsh.impl.oper.VppNshReaderFactory; import io.fd.honeycomb.vppnsh.impl.util.JVppNshProvider; -import net.jmob.guice.conf.core.ConfigurationModule; import io.fd.vpp.jvpp.nsh.future.FutureJVppNsh; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,11 +41,6 @@ public final class VppNshModule extends AbstractModule { @Override protected void configure() { - // TODO HONEYCOMB-207 workaround: - if (!isEnabled()) { - LOG.info("VppNshModule is disabled. Skipping module configuration."); - return; - } LOG.info("Configuring VppNsh module"); // Naming contexts @@ -70,19 +61,4 @@ public final class VppNshModule extends AbstractModule { Multibinder.newSetBinder(binder(), DataTreeInitializer.class).addBinding().to(VppNshInitializer.class); LOG.info("NSH module successfully configured"); } - - private static boolean isEnabled() { - final Injector injector = Guice.createInjector(new AbstractModule() { - @Override - protected void configure() { - // These are plugin specific config attributes - install(ConfigurationModule.create()); - requestInjection(VppNshConfiguration.class); - } - }); - - final VppNshConfiguration cfgAttributes = injector.getInstance(VppNshConfiguration.class); - LOG.debug("Configuration for VppNsh module: {}", cfgAttributes); - return cfgAttributes.isNshEnabled(); - } } diff --git a/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/cfgattrs/VppNshConfiguration.java b/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/cfgattrs/VppNshConfiguration.java deleted file mode 100755 index e6491509d..000000000 --- a/nsh/impl/src/main/java/io/fd/honeycomb/vppnsh/impl/cfgattrs/VppNshConfiguration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016 Intel 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.honeycomb.vppnsh.impl.cfgattrs; - -import com.google.common.base.MoreObjects; - -import net.jmob.guice.conf.core.BindConfig; -import net.jmob.guice.conf.core.InjectConfig; -import net.jmob.guice.conf.core.Syntax; - -@BindConfig(value = "vppnsh", syntax = Syntax.JSON) -public class VppNshConfiguration { - - public boolean isNshEnabled() { - return Boolean.valueOf(nshEnable); - } - - @InjectConfig("nsh-enabled") - public String nshEnable; - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("nshEnable", nshEnable) - .toString(); - } -} diff --git a/nsh/impl/src/main/resources/honeycomb-minimal-resources/config/vppnsh.json b/nsh/impl/src/main/resources/honeycomb-minimal-resources/config/vppnsh.json deleted file mode 100644 index b03a962f1..000000000 --- a/nsh/impl/src/main/resources/honeycomb-minimal-resources/config/vppnsh.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "nsh-enabled": "false" -} \ No newline at end of file diff --git a/samples/minimal-distribution/pom.xml b/samples/minimal-distribution/pom.xml index d3876790f..db4966684 100644 --- a/samples/minimal-distribution/pom.xml +++ b/samples/minimal-distribution/pom.xml @@ -30,10 +30,13 @@ -Xms128m -Xmx128m - io.fd.honeycomb.samples.distro.Main + io.fd.honeycomb.infra.distro.Main 1.16.12-SNAPSHOT 1.16.12-SNAPSHOT true + + io.fd.honeycomb.samples.interfaces.mapping.SampleInterfaceModule + diff --git a/samples/minimal-distribution/src/main/java/io/fd/honeycomb/samples/distro/Main.java b/samples/minimal-distribution/src/main/java/io/fd/honeycomb/samples/distro/Main.java deleted file mode 100644 index f6b38aa78..000000000 --- a/samples/minimal-distribution/src/main/java/io/fd/honeycomb/samples/distro/Main.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.honeycomb.samples.distro; - -import com.google.common.collect.Lists; -import com.google.inject.Module; -import io.fd.honeycomb.samples.interfaces.mapping.SampleInterfaceModule; -import java.util.List; - -public class Main { - - public static void main(String[] args) { - final List sampleModules = Lists.newArrayList(io.fd.honeycomb.infra.distro.Main.BASE_MODULES); - - sampleModules.add(new SampleInterfaceModule()); - - io.fd.honeycomb.infra.distro.Main.init(sampleModules); - } -} diff --git a/vpp-common/minimal-distribution/asciidoc/Readme.adoc b/vpp-common/minimal-distribution/asciidoc/Readme.adoc deleted file mode 100644 index 1da86caab..000000000 --- a/vpp-common/minimal-distribution/asciidoc/Readme.adoc +++ /dev/null @@ -1,3 +0,0 @@ -= minimal-distribution - -Overview of minimal-distribution \ No newline at end of file diff --git a/vpp-common/minimal-distribution/pom.xml b/vpp-common/minimal-distribution/pom.xml deleted file mode 100644 index 12d11ec1a..000000000 --- a/vpp-common/minimal-distribution/pom.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - io.fd.honeycomb.common - minimal-distribution-parent - 1.16.12-SNAPSHOT - ../../common/minimal-distribution-parent - - - 4.0.0 - io.fd.honeycomb.vpp - minimal-distribution - 1.16.12-SNAPSHOT - - - io.fd.honeycomb.vpp.distro.Main - 1.16.12-SNAPSHOT - 16.12-SNAPSHOT - 1.3 - - - - - - maven-compiler-plugin - - - org.codehaus.gmaven - groovy-maven-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - org.apache.maven.plugins - maven-dependency-plugin - - - maven-assembly-plugin - - - - - - - io.fd.honeycomb - minimal-distribution - ${honeycomb.min.distro.version} - - - ${project.groupId} - naming-context-api - ${project.version} - - - ${project.groupId} - naming-context-impl - ${project.version} - - - io.fd.vpp - jvpp-registry - ${jvpp.version} - - - io.fd.vpp - jvpp-core - ${jvpp.version} - - - ${project.groupId} - vpp-translate-utils - ${project.version} - - - - - junit - junit - test - - - org.mockito - mockito-core - test - - - com.google.inject.extensions - guice-testlib - ${guice.version} - test - - - org.hamcrest - hamcrest-all - ${hamcrest.version} - test - - - diff --git a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/ContextsReaderFactoryProvider.java b/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/ContextsReaderFactoryProvider.java deleted file mode 100644 index 35dd78e4e..000000000 --- a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/ContextsReaderFactoryProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import com.google.inject.Inject; -import com.google.inject.name.Named; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.vpp.context.ContextsReaderFactory; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; - -/** - * Mirror of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.context.impl.rev141210.ContextReaderModule - */ -public final class ContextsReaderFactoryProvider extends ProviderTrait { - - @Inject - @Named(ContextPipelineModule.HONEYCOMB_CONTEXT) - private DataBroker contextDataBroker; - - @Override - protected ContextsReaderFactory create() { - return new ContextsReaderFactory(contextDataBroker); - } -} diff --git a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppCoreProvider.java b/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppCoreProvider.java deleted file mode 100644 index b8334df55..000000000 --- a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppCoreProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import java.io.IOException; -import io.fd.vpp.jvpp.JVppRegistry; -import io.fd.vpp.jvpp.core.JVppCoreImpl; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; -import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Provides future API for jvpp-core plugin. Must be a singleton due to shutdown hook usage. Registers shutdown hook to - * free plugin's resources on shutdown. - */ -public final class JVppCoreProvider extends ProviderTrait { - - private static final Logger LOG = LoggerFactory.getLogger(JVppCoreProvider.class); - - @Inject - private JVppRegistry registry; - - @Override - protected FutureJVppCoreFacade create() { - try { - final JVppCoreImpl jVpp = new JVppCoreImpl(); - // Free jvpp-core plugin's resources on shutdown - Runtime.getRuntime().addShutdownHook(new Thread() { - - @Override - public void run() { - LOG.info("Unloading jvpp-core plugin"); - jVpp.close(); - LOG.info("Successfully unloaded jvpp-core plugin"); - } - }); - - LOG.info("Successfully loaded jvpp-core plugin"); - return new FutureJVppCoreFacade(registry, jVpp); - } catch (IOException e) { - throw new IllegalStateException("Unable to open VPP management connection", e); - } - } -} diff --git a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppRegistryProvider.java b/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppRegistryProvider.java deleted file mode 100644 index 9ecdd69ee..000000000 --- a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/JVppRegistryProvider.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import com.google.inject.Inject; -import io.fd.honeycomb.infra.distro.ProviderTrait; -import io.fd.honeycomb.translate.vpp.util.VppStatusListener; -import java.io.IOException; -import io.fd.vpp.jvpp.JVppRegistry; -import io.fd.vpp.jvpp.JVppRegistryImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Provides JVppRegistry. Must be a singleton due to shutdown hook usage. Registers shutdown hook to disconnect from - * VPP. - */ -public final class JVppRegistryProvider extends ProviderTrait { - - private static final Logger LOG = LoggerFactory.getLogger(JVppRegistryProvider.class); - - @Inject - private VppConfigAttributes config; - @Inject - private VppStatusListener vppStatus; - - @Override - protected JVppRegistryImpl create() { - try { - final JVppRegistryImpl registry = new JVppRegistryImpl(config.jvppConnectionName); - - // Closing JVpp connection with shutdown hook to erase the connection from VPP so HC will be able - // to connect next time. If JVM is force closed, this will not be executed and VPP connection - // with name from config will stay open and prevent next startup of HC to success - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - LOG.info("Disconnecting from VPP"); - if (vppStatus.isDown()) { - LOG.info("VPP is down. JVppRegistry cleanup is not needed. Exiting"); - return; - } - try { - registry.close(); - LOG.info("Successfully disconnected from VPP as {}", config.jvppConnectionName); - } catch (Exception e) { - LOG.warn("Unable to properly close jvpp registry", e); - } - } - }); - - LOG.info("JVpp connection opened successfully as: {}", config.jvppConnectionName); - return registry; - } catch (IOException e) { - throw new IllegalStateException("Unable to open VPP management connection", e); - } - } -} diff --git a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/Main.java b/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/Main.java deleted file mode 100644 index 821bd1ef9..000000000 --- a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/Main.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import com.google.common.collect.Lists; -import com.google.inject.Module; -import java.util.List; - -public class Main { - - public static void main(String[] args) { - final List sampleModules = Lists.newArrayList(io.fd.honeycomb.infra.distro.Main.BASE_MODULES); - - sampleModules.add(new VppCommonModule()); - - io.fd.honeycomb.infra.distro.Main.init(sampleModules); - } -} diff --git a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppCommonModule.java b/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppCommonModule.java deleted file mode 100644 index 957819f28..000000000 --- a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppCommonModule.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import com.google.inject.AbstractModule; -import com.google.inject.Singleton; -import com.google.inject.multibindings.Multibinder; -import io.fd.honeycomb.translate.read.ReaderFactory; -import io.fd.honeycomb.translate.vpp.util.VppStatusListener; -import net.jmob.guice.conf.core.ConfigurationModule; -import io.fd.vpp.jvpp.JVppRegistry; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -public final class VppCommonModule extends AbstractModule { - protected void configure() { - - install(ConfigurationModule.create()); - // Inject non-dependency configuration - requestInjection(VppConfigAttributes.class); - - bind(VppStatusListener.class).toInstance(new VppStatusListener()); - bind(JVppRegistry.class).toProvider(JVppRegistryProvider.class).in(Singleton.class); - bind(FutureJVppCore.class).toProvider(JVppCoreProvider.class).in(Singleton.class); - - // Naming contexts reader exposing context storage over REST/HONEYCOMB_NETCONF - final Multibinder readerBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); - readerBinder.addBinding().toProvider(ContextsReaderFactoryProvider.class).in(Singleton.class); - } - -} diff --git a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppConfigAttributes.java b/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppConfigAttributes.java deleted file mode 100644 index 26b5a8385..000000000 --- a/vpp-common/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/distro/VppConfigAttributes.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import net.jmob.guice.conf.core.BindConfig; -import net.jmob.guice.conf.core.InjectConfig; -import net.jmob.guice.conf.core.Syntax; - -@BindConfig(value = "jvpp", syntax = Syntax.JSON) -public class VppConfigAttributes { - - @InjectConfig("jvpp-connection-name") - public String jvppConnectionName; -} diff --git a/vpp-common/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/jvpp.json b/vpp-common/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/jvpp.json deleted file mode 100644 index 1d411872e..000000000 --- a/vpp-common/minimal-distribution/src/main/resources/honeycomb-minimal-resources/config/jvpp.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "jvpp-connection-name": "honeycomb" -} \ No newline at end of file diff --git a/vpp-common/minimal-distribution/src/test/java/io/fd/honeycomb/vpp/distro/VppCommonModuleTest.java b/vpp-common/minimal-distribution/src/test/java/io/fd/honeycomb/vpp/distro/VppCommonModuleTest.java deleted file mode 100644 index f59134812..000000000 --- a/vpp-common/minimal-distribution/src/test/java/io/fd/honeycomb/vpp/distro/VppCommonModuleTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.honeycomb.vpp.distro; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.Matchers.empty; -import static org.junit.Assert.assertThat; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.name.Named; -import com.google.inject.testing.fieldbinder.Bind; -import com.google.inject.testing.fieldbinder.BoundFieldModule; -import io.fd.honeycomb.translate.read.ReaderFactory; -import java.util.HashSet; -import java.util.Set; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.controller.md.sal.binding.api.DataBroker; - -public class VppCommonModuleTest { - - @Named("honeycomb-context") - @Bind - @Mock - private DataBroker honeycombContext; - - @Inject - private Set readerFactories = new HashSet<>(); - - @Test - public void testConfigure() throws Exception { - initMocks(this); - Guice.createInjector(new VppCommonModule(), BoundFieldModule.of(this)).injectMembers(this); - assertThat(readerFactories, is(not(empty()))); - } -} \ No newline at end of file diff --git a/vpp-common/minimal-distribution/src/test/resources/jvpp.json b/vpp-common/minimal-distribution/src/test/resources/jvpp.json deleted file mode 100644 index 1d411872e..000000000 --- a/vpp-common/minimal-distribution/src/test/resources/jvpp.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "jvpp-connection-name": "honeycomb" -} \ No newline at end of file diff --git a/vpp-common/pom.xml b/vpp-common/pom.xml index d6833cdd3..e7180aea2 100644 --- a/vpp-common/pom.xml +++ b/vpp-common/pom.xml @@ -34,7 +34,7 @@ vpp-translate-utils naming-context-api naming-context-impl - minimal-distribution + vpp-common-integration vpp-impl-parent vpp-translate-test diff --git a/vpp-common/vpp-common-integration/asciidoc/Readme.adoc b/vpp-common/vpp-common-integration/asciidoc/Readme.adoc new file mode 100644 index 000000000..8c18a3eb2 --- /dev/null +++ b/vpp-common/vpp-common-integration/asciidoc/Readme.adoc @@ -0,0 +1,3 @@ += vpp-common-integration + +Overview of vpp-common-integration \ No newline at end of file diff --git a/vpp-common/vpp-common-integration/pom.xml b/vpp-common/vpp-common-integration/pom.xml new file mode 100644 index 000000000..2cb031ec8 --- /dev/null +++ b/vpp-common/vpp-common-integration/pom.xml @@ -0,0 +1,116 @@ + + + + + + io.fd.honeycomb.common + impl-parent + 1.16.12-SNAPSHOT + ../../common/impl-parent + + + 4.0.0 + io.fd.honeycomb.vpp + vpp-common-integration + 1.16.12-SNAPSHOT + + + 1.16.12-SNAPSHOT + 16.12-SNAPSHOT + 1.3 + + + + + + maven-compiler-plugin + + + org.codehaus.gmaven + groovy-maven-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + + + maven-assembly-plugin + + + + + + + io.fd.honeycomb + minimal-distribution + ${honeycomb.min.distro.version} + + + ${project.groupId} + naming-context-api + ${project.version} + + + ${project.groupId} + naming-context-impl + ${project.version} + + + io.fd.vpp + jvpp-registry + ${jvpp.version} + + + io.fd.vpp + jvpp-core + ${jvpp.version} + + + ${project.groupId} + vpp-translate-utils + ${project.version} + + + + + junit + junit + test + + + org.mockito + mockito-core + test + + + com.google.inject.extensions + guice-testlib + ${guice.version} + test + + + org.hamcrest + hamcrest-all + ${hamcrest.version} + test + + + diff --git a/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/ContextsReaderFactoryProvider.java b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/ContextsReaderFactoryProvider.java new file mode 100644 index 000000000..d33b8b717 --- /dev/null +++ b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/ContextsReaderFactoryProvider.java @@ -0,0 +1,40 @@ +/* + * 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.honeycomb.vpp.common.integration; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.infra.distro.data.context.ContextPipelineModule; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.vpp.context.ContextsReaderFactory; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; + +/** + * Mirror of org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.context.impl.rev141210.ContextReaderModule + */ +public final class ContextsReaderFactoryProvider extends ProviderTrait { + + @Inject + @Named(ContextPipelineModule.HONEYCOMB_CONTEXT) + private DataBroker contextDataBroker; + + @Override + protected ContextsReaderFactory create() { + return new ContextsReaderFactory(contextDataBroker); + } +} diff --git a/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppCoreProvider.java b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppCoreProvider.java new file mode 100644 index 000000000..bbd30fbfb --- /dev/null +++ b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppCoreProvider.java @@ -0,0 +1,61 @@ +/* + * 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.honeycomb.vpp.common.integration; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import java.io.IOException; +import io.fd.vpp.jvpp.JVppRegistry; +import io.fd.vpp.jvpp.core.JVppCoreImpl; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import io.fd.vpp.jvpp.core.future.FutureJVppCoreFacade; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides future API for jvpp-core plugin. Must be a singleton due to shutdown hook usage. Registers shutdown hook to + * free plugin's resources on shutdown. + */ +public final class JVppCoreProvider extends ProviderTrait { + + private static final Logger LOG = LoggerFactory.getLogger(JVppCoreProvider.class); + + @Inject + private JVppRegistry registry; + + @Override + protected FutureJVppCoreFacade create() { + try { + final JVppCoreImpl jVpp = new JVppCoreImpl(); + // Free jvpp-core plugin's resources on shutdown + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + LOG.info("Unloading jvpp-core plugin"); + jVpp.close(); + LOG.info("Successfully unloaded jvpp-core plugin"); + } + }); + + LOG.info("Successfully loaded jvpp-core plugin"); + return new FutureJVppCoreFacade(registry, jVpp); + } catch (IOException e) { + throw new IllegalStateException("Unable to open VPP management connection", e); + } + } +} diff --git a/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppRegistryProvider.java b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppRegistryProvider.java new file mode 100644 index 000000000..fa1d47480 --- /dev/null +++ b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/JVppRegistryProvider.java @@ -0,0 +1,72 @@ +/* + * 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.honeycomb.vpp.common.integration; + +import com.google.inject.Inject; +import io.fd.honeycomb.infra.distro.ProviderTrait; +import io.fd.honeycomb.translate.vpp.util.VppStatusListener; +import java.io.IOException; +import io.fd.vpp.jvpp.JVppRegistry; +import io.fd.vpp.jvpp.JVppRegistryImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides JVppRegistry. Must be a singleton due to shutdown hook usage. Registers shutdown hook to disconnect from + * VPP. + */ +public final class JVppRegistryProvider extends ProviderTrait { + + private static final Logger LOG = LoggerFactory.getLogger(JVppRegistryProvider.class); + + @Inject + private VppConfigAttributes config; + @Inject + private VppStatusListener vppStatus; + + @Override + protected JVppRegistryImpl create() { + try { + final JVppRegistryImpl registry = new JVppRegistryImpl(config.jvppConnectionName); + + // Closing JVpp connection with shutdown hook to erase the connection from VPP so HC will be able + // to connect next time. If JVM is force closed, this will not be executed and VPP connection + // with name from config will stay open and prevent next startup of HC to success + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + LOG.info("Disconnecting from VPP"); + if (vppStatus.isDown()) { + LOG.info("VPP is down. JVppRegistry cleanup is not needed. Exiting"); + return; + } + try { + registry.close(); + LOG.info("Successfully disconnected from VPP as {}", config.jvppConnectionName); + } catch (Exception e) { + LOG.warn("Unable to properly close jvpp registry", e); + } + } + }); + + LOG.info("JVpp connection opened successfully as: {}", config.jvppConnectionName); + return registry; + } catch (IOException e) { + throw new IllegalStateException("Unable to open VPP management connection", e); + } + } +} diff --git a/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppCommonModule.java b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppCommonModule.java new file mode 100644 index 000000000..9bdba1b14 --- /dev/null +++ b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppCommonModule.java @@ -0,0 +1,44 @@ +/* + * 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.honeycomb.vpp.common.integration; + +import com.google.inject.AbstractModule; +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.vpp.util.VppStatusListener; +import net.jmob.guice.conf.core.ConfigurationModule; +import io.fd.vpp.jvpp.JVppRegistry; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public final class VppCommonModule extends AbstractModule { + protected void configure() { + + install(ConfigurationModule.create()); + // Inject non-dependency configuration + requestInjection(VppConfigAttributes.class); + + bind(VppStatusListener.class).toInstance(new VppStatusListener()); + bind(JVppRegistry.class).toProvider(JVppRegistryProvider.class).in(Singleton.class); + bind(FutureJVppCore.class).toProvider(JVppCoreProvider.class).in(Singleton.class); + + // Naming contexts reader exposing context storage over REST/HONEYCOMB_NETCONF + final Multibinder readerBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerBinder.addBinding().toProvider(ContextsReaderFactoryProvider.class).in(Singleton.class); + } + +} diff --git a/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppConfigAttributes.java b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppConfigAttributes.java new file mode 100644 index 000000000..af06e05db --- /dev/null +++ b/vpp-common/vpp-common-integration/src/main/java/io/fd/honeycomb/vpp/common/integration/VppConfigAttributes.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.vpp.common.integration; + +import net.jmob.guice.conf.core.BindConfig; +import net.jmob.guice.conf.core.InjectConfig; +import net.jmob.guice.conf.core.Syntax; + +@BindConfig(value = "jvpp", syntax = Syntax.JSON) +public class VppConfigAttributes { + + @InjectConfig("jvpp-connection-name") + public String jvppConnectionName; +} diff --git a/vpp-common/vpp-common-integration/src/main/resources/honeycomb-minimal-resources/config/jvpp.json b/vpp-common/vpp-common-integration/src/main/resources/honeycomb-minimal-resources/config/jvpp.json new file mode 100644 index 000000000..1d411872e --- /dev/null +++ b/vpp-common/vpp-common-integration/src/main/resources/honeycomb-minimal-resources/config/jvpp.json @@ -0,0 +1,3 @@ +{ + "jvpp-connection-name": "honeycomb" +} \ No newline at end of file diff --git a/vpp-common/vpp-common-integration/src/test/java/io/fd/honeycomb/vpp/common/integration/VppCommonModuleTest.java b/vpp-common/vpp-common-integration/src/test/java/io/fd/honeycomb/vpp/common/integration/VppCommonModuleTest.java new file mode 100644 index 000000000..476e15919 --- /dev/null +++ b/vpp-common/vpp-common-integration/src/test/java/io/fd/honeycomb/vpp/common/integration/VppCommonModuleTest.java @@ -0,0 +1,53 @@ +/* + * 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.honeycomb.vpp.common.integration; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.Matchers.empty; +import static org.junit.Assert.assertThat; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.name.Named; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import io.fd.honeycomb.translate.read.ReaderFactory; +import java.util.HashSet; +import java.util.Set; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; + +public class VppCommonModuleTest { + + @Named("honeycomb-context") + @Bind + @Mock + private DataBroker honeycombContext; + + @Inject + private Set readerFactories = new HashSet<>(); + + @Test + public void testConfigure() throws Exception { + initMocks(this); + Guice.createInjector(new VppCommonModule(), BoundFieldModule.of(this)).injectMembers(this); + assertThat(readerFactories, is(not(empty()))); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-common-integration/src/test/resources/jvpp.json b/vpp-common/vpp-common-integration/src/test/resources/jvpp.json new file mode 100644 index 000000000..1d411872e --- /dev/null +++ b/vpp-common/vpp-common-integration/src/test/resources/jvpp.json @@ -0,0 +1,3 @@ +{ + "jvpp-connection-name": "honeycomb" +} \ No newline at end of file diff --git a/vpp-integration/minimal-distribution/pom.xml b/vpp-integration/minimal-distribution/pom.xml index 7e1aa0241..36d1e0f1a 100644 --- a/vpp-integration/minimal-distribution/pom.xml +++ b/vpp-integration/minimal-distribution/pom.xml @@ -29,11 +29,19 @@ 1.16.12-SNAPSHOT - io.fd.honeycomb.vpp.integration.distro.Main + io.fd.honeycomb.infra.distro.Main 1.16.12-SNAPSHOT 1.16.12-SNAPSHOT - 1.16.12-SNAPSHOT + 1.16.12-SNAPSHOT 1.16.12-SNAPSHOT + + + io.fd.honeycomb.vpp.common.integration.VppCommonModule, + io.fd.honeycomb.lisp.LispModule, + io.fd.honeycomb.translate.v3po.V3poModule, + // io.fd.honeycomb.vppnsh.impl.VppNshModule + + @@ -62,8 +70,8 @@ io.fd.honeycomb.vpp - minimal-distribution - ${vpp.common.min.distro.version} + vpp-common-integration + ${vpp.common.integration.version} io.fd.honeycomb.v3po diff --git a/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java b/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java deleted file mode 100644 index 04377c382..000000000 --- a/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.honeycomb.vpp.integration.distro; - -import com.google.common.collect.Lists; -import com.google.inject.Module; -import io.fd.honeycomb.lisp.LispModule; -import io.fd.honeycomb.translate.v3po.V3poModule; -import io.fd.honeycomb.vpp.distro.VppCommonModule; -import io.fd.honeycomb.vppnsh.impl.VppNshModule; -import java.util.List; - -public class Main { - - public static void main(String[] args) { - final List sampleModules = Lists.newArrayList(io.fd.honeycomb.infra.distro.Main.BASE_MODULES); - - // All the plugins should be listed here - sampleModules.add(new VppCommonModule()); - sampleModules.add(new V3poModule()); - sampleModules.add(new LispModule()); - sampleModules.add(new VppNshModule()); - - io.fd.honeycomb.infra.distro.Main.init(sampleModules); - } -} -- cgit 1.2.3-korg