package io.fd.honeycomb.infra.bgp.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.inject.ConfigurationException;
import com.google.inject.CreationException;
import com.google.inject.Injector;
-import com.google.inject.Module;
import com.google.inject.ProvisionException;
import io.fd.honeycomb.infra.bgp.BgpConfiguration;
import io.fd.honeycomb.infra.bgp.BgpServerProvider;
-import java.util.Set;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighbors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
public static void main(String[] args) {
- final ClassLoader classLoader = Main.class.getClassLoader();
- init(loadActiveModules(aggregateResources(STANDARD_MODULES_RELATIVE_PATH, classLoader)));
+ init();
}
/**
* Initialize the Honeycomb with provided modules
*/
- public static Injector init(final Set<? extends Module> modules) {
+ public static Injector init() {
try {
- Injector injector = io.fd.honeycomb.infra.distro.Main.init(modules);
+ Injector injector = io.fd.honeycomb.infra.distro.Main.init();
final BgpConfiguration bgpAttributes = injector.getInstance(BgpConfiguration.class);
if (bgpAttributes.isBgpEnabled()) {
--- /dev/null
+{
+ "modules-resource-path": "../modules/"
+}
\ No newline at end of file
package io.fd.honeycomb.infra.bgp.distro;
-import static com.google.common.collect.ImmutableSet.of;
-
import com.google.common.io.ByteStreams;
-import com.google.inject.Module;
import com.mashape.unirest.http.Unirest;
-import io.fd.honeycomb.infra.bgp.BgpConfigurationModule;
-import io.fd.honeycomb.infra.bgp.BgpExtensionsModule;
-import io.fd.honeycomb.infra.bgp.BgpModule;
-import io.fd.honeycomb.infra.bgp.BgpReadersModule;
-import io.fd.honeycomb.infra.bgp.BgpWritersModule;
-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.InetAddress;
import java.net.Socket;
-import java.util.Set;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
private static final byte BGP_OPEN_MSG_TYPE = 1;
private static final int BGP_PORT = 1790;
- public static final Set<Module> BASE_MODULES = of(
- new YangBindingProviderModule(),
- new SchemaModule(),
- new ConfigAndOperationalPipelineModule(),
- new ContextPipelineModule(),
- new InitializerPipelineModule(),
- new NetconfModule(),
- new NetconfReadersModule(),
- new RestconfModule(),
- new CfgAttrsModule(),
- new BgpModule(),
- new BgpExtensionsModule(),
- new BgpReadersModule(),
- new BgpWritersModule(),
- new BgpConfigurationModule());
-
@Before
public void setUp() throws Exception {
SSLContext sslcontext = SSLContexts.custom()
@Test(timeout = 120000)
public void test() throws Exception {
- io.fd.honeycomb.infra.bgp.distro.Main.init(BASE_MODULES);
+ io.fd.honeycomb.infra.bgp.distro.Main.init();
LOG.info("Testing Honeycomb BGP distribution");
assertBgp();
}
--- /dev/null
+{
+ "modules-resource-path": "base-distro-test-modules"
+}
\ No newline at end of file
--- /dev/null
+io.fd.honeycomb.infra.bgp.BgpConfigurationModule
+io.fd.honeycomb.infra.bgp.BgpExtensionsModule
+io.fd.honeycomb.infra.bgp.BgpModule
+io.fd.honeycomb.infra.bgp.BgpReadersModule
+io.fd.honeycomb.infra.bgp.BgpWritersModule
+io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule
+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.schema.SchemaModule
+io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule
\ No newline at end of file
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 static com.google.inject.Guice.createInjector;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.ConfigurationException;
import com.google.inject.CreationException;
import com.google.inject.Guice;
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.activation.ActivationModule;
+import io.fd.honeycomb.infra.distro.activation.ActiveModules;
import io.fd.honeycomb.infra.distro.cfgattrs.HoneycombConfiguration;
import io.fd.honeycomb.infra.distro.initializer.InitializerPipelineModule;
import io.fd.honeycomb.infra.distro.netconf.HoneycombNotification2NetconfProvider;
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 java.util.Set;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.opendaylight.netconf.mapping.api.NetconfOperationServiceFactory;
}
public static void main(String[] args) {
- final ClassLoader classLoader = Main.class.getClassLoader();
- init(loadActiveModules(aggregateResources(STANDARD_MODULES_RELATIVE_PATH, classLoader)));
+ init();
}
/**
* Initialize the Honeycomb with provided modules
*/
- public static Injector init(final Set<? extends Module> modules) {
+ public static Injector init() {
try {
LOG.info("Starting honeycomb");
- Injector injector = Guice.createInjector(modules);
+ final ActivationModule activationModule = new ActivationModule();
+ // creating child injector does not work in this case, so just create injector, and does not store ref
+ // to it, or its active modules instance
+ Injector injector = createInjector(ImmutableSet.<Module>builder()
+ .add(activationModule)
+ .addAll(createInjector(activationModule).getInstance(ActiveModules.class).createModuleInstances())
+ .build());
+
LOG.info("Honeycomb configuration: {}", injector.getInstance(HoneycombConfiguration.class));
// Log all bindings
--- /dev/null
+/*
+ * 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.activation;
+
+import java.util.Optional;
+import net.jmob.guice.conf.core.BindConfig;
+import net.jmob.guice.conf.core.InjectConfig;
+import net.jmob.guice.conf.core.Syntax;
+
+@BindConfig(value = "activation", syntax = Syntax.JSON)
+public class ActivationConfig {
+
+ @InjectConfig("modules-resource-path")
+ private String modulesResourcePath;
+
+ public String getModulesResourcePath() {
+ return Optional.ofNullable(modulesResourcePath).orElse("../modules/");
+ }
+}
--- /dev/null
+/*
+ * 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.activation;
+
+import com.google.inject.AbstractModule;
+import net.jmob.guice.conf.core.ConfigurationModule;
+
+/**
+ * Module that provides set of modules activated by distribution and binds this set to be available
+ */
+public class ActivationModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ install(ConfigurationModule.create());
+ requestInjection(ActivationConfig.class);
+ bind(ActiveModules.class).toProvider(ActiveModuleProvider.class).asEagerSingleton();
+ }
+}
/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * 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.
* limitations under the License.
*/
-package io.fd.honeycomb.infra.distro;
+package io.fd.honeycomb.infra.distro.activation;
import com.google.common.collect.ImmutableList;
+import com.google.inject.Inject;
import com.google.inject.Module;
+import com.google.inject.Provider;
import java.io.File;
import java.io.IOException;
import java.net.URI;
/**
* Provides list of active modules for distribution
*/
-public class ActiveModuleProvider {
+class ActiveModuleProvider implements Provider<ActiveModules> {
- public static final String STANDARD_MODULES_RELATIVE_PATH = "../modules/";
private static final Logger LOG = LoggerFactory.getLogger(ActiveModuleProvider.class);
+ @Inject
+ private ActivationConfig config;
+
+ @Override
+ public ActiveModules get() {
+ return new ActiveModules(loadActiveModules(
+ aggregateResources(config.getModulesResourcePath(), Thread.currentThread().getContextClassLoader())));
+ }
+
/**
* Provide unique set of active modules filtered from provided resources
*/
- public static Set<Module> loadActiveModules(@Nonnull final List<String> moduleNames) {
+ static Set<Class<? extends Module>> loadActiveModules(@Nonnull final List<String> moduleNames) {
final ClassLoader classLoader = ActiveModuleProvider.class.getClassLoader();
LOG.info("Reading active modules configuration for distribution");
.filter(nonEmptyLine -> !nonEmptyLine.startsWith("//"))
// filter duplicates
.distinct()
- .map(validLine -> nameToClass(validLine, classLoader))
+ .map(validLine -> moduleNameToClass(validLine, classLoader))
// filters out classes that are not modules
.filter(ActiveModuleProvider::filterNonModules)
- .map(ActiveModuleProvider::classToInstance)
.collect(Collectors.toSet());
}
/**
* Loads class by provided name
*/
- private static Class<?> nameToClass(final String name,
- final ClassLoader classLoader) {
+ private static Class<? extends Module> moduleNameToClass(final String name,
+ final ClassLoader classLoader) {
try {
LOG.info("Loading module class {}", name);
- return classLoader.loadClass(name);
+ return (Class<? extends Module>) 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);
- }
- }
}
--- /dev/null
+/*
+ * 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.activation;
+
+import static java.lang.String.format;
+
+import com.google.inject.Module;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Provides static set of active activeModulesClasses
+ */
+public class ActiveModules {
+ private final Set<Class<? extends Module>> activeModulesClasses;
+
+ public ActiveModules(final Set<Class<? extends Module>> activeModulesClasses) {
+ this.activeModulesClasses = activeModulesClasses;
+ }
+
+ public Set<Class<? extends Module>> getActiveModulesClasses() {
+ return activeModulesClasses;
+ }
+
+ public Set<? extends Module> createModuleInstances() {
+ return activeModulesClasses.stream()
+ .map(moduleClass -> {
+ try {
+ return moduleClass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new IllegalStateException(format("Unable to create instance of module %s", moduleClass),
+ e);
+ }
+ }).collect(Collectors.toSet());
+ }
+
+ @Override
+ public String toString() {
+ return "ActiveModules{" +
+ "activeModulesClasses=" + activeModulesClasses +
+ '}';
+ }
+}
.map(YangBindingProviderModule::urlToString)
.flatMap(content -> Lists.newArrayList(content.split("\n")).stream())
.filter(line -> !Strings.isNullOrEmpty(line.trim()))
+ .distinct()
.map(YangBindingProviderModule::loadClass)
.forEach(providerClass -> {
LOG.debug("ModuleProvider found for {}", providerClass);
--- /dev/null
+{
+ "modules-resource-path": "../modules/"
+}
\ No newline at end of file
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.Properties;
-import java.util.Set;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
private static final String NETCONF_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0";
private static final int HELLO_WAIT = 2500;
- public static final Set<Module> 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()
*/
@Test(timeout = 120000)
public void test() throws Exception {
- Main.init(BASE_MODULES);
+ Main.init();
LOG.info("Testing Honeycomb base distribution");
LOG.info("Testing NETCONF TCP");
/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * 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.
* limitations under the License.
*/
-package io.fd.honeycomb.infra.distro;
+package io.fd.honeycomb.infra.distro.activation;
import static com.google.common.collect.ImmutableList.of;
@Test
public void testLoadActiveModulesSuccessfull() {
- final ImmutableList rawResources = of(
+ final ImmutableList<String> 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$NonModule"
);
-
- final Set<Module> activeModules = ActiveModuleProvider.loadActiveModules(rawResources);
+ // have to be without wildcard, otherwise mockito has problem with it
+ final Set<Module> activeModules = (Set<Module>) new ActiveModules(ActiveModuleProvider.loadActiveModules(rawResources)).createModuleInstances();
// 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
@Test
public void testAggregateResourcesNonEmpty() {
final List<String> aggregatedResources =
- ActiveModuleProvider.aggregateResources("./modules", this.getClass().getClassLoader());
+ ActiveModuleProvider.aggregateResources("modules", this.getClass().getClassLoader());
assertThat(aggregatedResources, hasSize(5));
assertThat(aggregatedResources, hasItems(" Non-commented non-trimmed",
"//Commented",
--- /dev/null
+{
+ "modules-resource-path": "base-distro-test-modules"
+}
\ No newline at end of file
--- /dev/null
+io.fd.honeycomb.infra.distro.cfgattrs.CfgAttrsModule
+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.schema.SchemaModule
+io.fd.honeycomb.infra.distro.schema.YangBindingProviderModule
\ No newline at end of file