From 11ea15fc1a90604c8edd71a26b9f9d9bc451d650 Mon Sep 17 00:00:00 2001 From: cheddar Date: Mon, 17 Jun 2013 10:53:50 -0700 Subject: [PATCH] 1) Introduce Jetty 8 2) Fix up modules based on exceptions at startup for MasterMain --- client/pom.xml | 12 +- .../java/com/metamx/druid/QueryableNode.java | 12 +- .../curator/discovery/DiscoveryModule.java | 9 +- .../com/metamx/druid/http/BrokerNode.java | 19 +- .../com/metamx/druid/http/QueryServlet.java | 3 +- ...igFactoryModule.java => ConfigModule.java} | 8 +- .../CuratorDiscoveryConfig.java | 2 +- .../druid/initialization/DruidNodeConfig.java | 4 +- .../druid/initialization/EmitterModule.java | 9 +- .../initialization/HttpEmitterConfig.java | 8 +- .../initialization/HttpEmitterModule.java | 6 +- .../druid/initialization/Initialization.java | 62 ++++- .../JettyServerInitializer.java | 11 + .../initialization/JettyServerModule.java | 62 +++++ common/pom.xml | 4 + .../metamx/druid/config/ConfigManager.java | 17 +- .../druid/config/ConfigManagerConfig.java | 22 +- .../druid/config/ConfigManagerProvider.java | 74 ++++++ .../java/com/metamx/druid/db/DbConnector.java | 27 ++- .../metamx/druid/db/DbConnectorConfig.java | 2 +- .../com/metamx/druid/db/DbTablesConfig.java | 55 ++++- .../metamx/druid/guice/ConfigProvider.java | 13 +- .../druid/guice/DruidSecondaryModule.java | 11 +- .../druid/guice/JsonConfigProvider.java | 69 ++---- .../metamx/druid/guice/JsonConfigurator.java | 94 ++++++++ examples/pom.xml | 105 -------- indexing-service/pom.xml | 4 +- .../http/IndexerCoordinatorNode.java | 61 ++--- .../http/IndexerCoordinatorResource.java | 8 - .../http/OldIndexerCoordinatorResource.java | 6 +- .../worker/executor/ExecutorNode.java | 12 +- .../indexing/worker/http/WorkerNode.java | 20 +- pom.xml | 30 ++- realtime/pom.xml | 4 +- .../metamx/druid/realtime/RealtimeNode.java | 6 +- server/pom.xml | 4 +- .../metamx/druid/db/DatabaseRuleManager.java | 12 +- .../druid/db/DatabaseRuleManagerConfig.java | 27 ++- .../druid/db/DatabaseRuleManagerProvider.java | 79 ++++++ .../db/DatabaseSegmentManagerProvider.java | 81 +++++++ .../metamx/druid/guice/HttpClientModule.java | 11 +- .../com/metamx/druid/guice/MasterModule.java | 83 ++++--- .../com/metamx/druid/http/ComputeNode.java | 10 +- .../com/metamx/druid/http/MasterMain.java | 228 +++--------------- .../metamx/druid/http/MasterRedirectInfo.java | 47 ++++ .../com/metamx/druid/http/RedirectFilter.java | 2 + .../metamx/druid/http/RedirectServlet.java | 2 + .../com/metamx/druid/master/DruidMaster.java | 4 + .../druid/master/LoadQueueTaskMaster.java | 2 + .../metrics/DruidMonitorSchedulerConfig.java | 26 ++ .../metamx/druid/metrics/MetricsModule.java | 15 +- 51 files changed, 948 insertions(+), 556 deletions(-) rename client/src/main/java/com/metamx/druid/initialization/{ConfigFactoryModule.java => ConfigModule.java} (80%) create mode 100644 client/src/main/java/com/metamx/druid/initialization/JettyServerInitializer.java create mode 100644 client/src/main/java/com/metamx/druid/initialization/JettyServerModule.java create mode 100644 common/src/main/java/com/metamx/druid/config/ConfigManagerProvider.java create mode 100644 common/src/main/java/com/metamx/druid/guice/JsonConfigurator.java create mode 100644 server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerProvider.java create mode 100644 server/src/main/java/com/metamx/druid/db/DatabaseSegmentManagerProvider.java create mode 100644 server/src/main/java/com/metamx/druid/http/MasterRedirectInfo.java create mode 100644 server/src/main/java/com/metamx/druid/metrics/DruidMonitorSchedulerConfig.java diff --git a/client/pom.xml b/client/pom.xml index 69e2999ec32..10268136193 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -86,12 +86,16 @@ curator-x-discovery - org.mortbay.jetty - jetty + org.eclipse.jetty + jetty-server - org.mortbay.jetty - jetty-util + org.eclipse.jetty + jetty-servlet + + + org.eclipse.jetty + jetty-servlets com.google.guava diff --git a/client/src/main/java/com/metamx/druid/QueryableNode.java b/client/src/main/java/com/metamx/druid/QueryableNode.java index ef8a995295b..ce70dca4398 100644 --- a/client/src/main/java/com/metamx/druid/QueryableNode.java +++ b/client/src/main/java/com/metamx/druid/QueryableNode.java @@ -43,6 +43,7 @@ import com.metamx.druid.coordination.DataSegmentAnnouncer; import com.metamx.druid.coordination.DruidServerMetadata; import com.metamx.druid.curator.CuratorConfig; import com.metamx.druid.curator.announcement.Announcer; +import com.metamx.druid.guice.JsonConfigurator; import com.metamx.druid.http.RequestLogger; import com.metamx.druid.initialization.Initialization; import com.metamx.druid.initialization.ServerConfig; @@ -60,10 +61,11 @@ import com.metamx.metrics.MonitorScheduler; import com.metamx.metrics.MonitorSchedulerConfig; import com.metamx.metrics.SysMonitor; import org.apache.curator.framework.CuratorFramework; +import org.eclipse.jetty.server.Server; import org.joda.time.Duration; -import org.mortbay.jetty.Server; import org.skife.config.ConfigurationObjectFactory; +import javax.validation.Validation; import java.io.IOException; import java.lang.reflect.Field; import java.util.Arrays; @@ -83,6 +85,7 @@ public abstract class QueryableNode extends Registering private final Properties props; private final ConfigurationObjectFactory configFactory; private final String nodeType; + private final JsonConfigurator jsonConfigurator; private DruidServerMetadata druidServerMetadata = null; private ServiceEmitter emitter = null; @@ -124,6 +127,8 @@ public abstract class QueryableNode extends Registering Preconditions.checkNotNull(smileMapper, "smileMapper"); Preconditions.checkNotNull(configFactory, "configFactory"); + this.jsonConfigurator = new JsonConfigurator(jsonMapper, Validation.buildDefaultValidatorFactory().getValidator()); + Preconditions.checkState(smileMapper.getJsonFactory() instanceof SmileFactory, "smileMapper should use smile."); this.nodeType = nodeType; } @@ -245,6 +250,11 @@ public abstract class QueryableNode extends Registering return configFactory; } + public JsonConfigurator getJsonConfigurator() + { + return jsonConfigurator; + } + public DruidServerMetadata getDruidServerMetadata() { initializeDruidServerMetadata(); diff --git a/client/src/main/java/com/metamx/druid/curator/discovery/DiscoveryModule.java b/client/src/main/java/com/metamx/druid/curator/discovery/DiscoveryModule.java index c5a2c701bf8..aa386977403 100644 --- a/client/src/main/java/com/metamx/druid/curator/discovery/DiscoveryModule.java +++ b/client/src/main/java/com/metamx/druid/curator/discovery/DiscoveryModule.java @@ -1,5 +1,6 @@ package com.metamx.druid.curator.discovery; +import com.google.common.base.Supplier; import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Provides; @@ -26,18 +27,18 @@ public class DiscoveryModule implements Module @Provides @LazySingleton public ServiceDiscovery getServiceDiscovery( CuratorFramework curator, - CuratorDiscoveryConfig config, + Supplier config, Lifecycle lifecycle ) throws Exception { - return Initialization.makeServiceDiscoveryClient(curator, config, lifecycle); + return Initialization.makeServiceDiscoveryClient(curator, config.get(), lifecycle); } @Provides @LazySingleton public ServiceInstanceFactory getServiceInstanceFactory( - DruidNodeConfig nodeConfig + Supplier nodeConfig ) { - return Initialization.makeServiceInstanceFactory(nodeConfig); + return Initialization.makeServiceInstanceFactory(nodeConfig.get()); } } diff --git a/client/src/main/java/com/metamx/druid/http/BrokerNode.java b/client/src/main/java/com/metamx/druid/http/BrokerNode.java index 6fd5b2e8004..4fbdf78f0f0 100644 --- a/client/src/main/java/com/metamx/druid/http/BrokerNode.java +++ b/client/src/main/java/com/metamx/druid/http/BrokerNode.java @@ -57,9 +57,9 @@ import com.metamx.http.client.HttpClientInit; import com.metamx.metrics.Monitor; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.x.discovery.ServiceDiscovery; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.servlet.GzipFilter; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlets.GzipFilter; import org.skife.config.ConfigurationObjectFactory; import java.util.List; @@ -210,19 +210,22 @@ public class BrokerNode extends QueryableNode theModules.addAll(extraModules); final Injector injector = Guice.createInjector(theModules); - final Context root = new Context(getServer(), "/", Context.SESSIONS); + final ServletContextHandler root = new ServletContextHandler(); + root.setContextPath("/"); root.addServlet(new ServletHolder(new StatusServlet()), "/status"); root.addServlet( - new ServletHolder(new QueryServlet(getJsonMapper(), getSmileMapper(), texasRanger, getEmitter(), getRequestLogger())), + new ServletHolder( + new QueryServlet(getJsonMapper(), getSmileMapper(), texasRanger, getEmitter(), getRequestLogger()) + ), "/druid/v2/*" ); - root.addFilter(GzipFilter.class, "/*", 0); + root.addFilter(GzipFilter.class, "/*", null); root.addEventListener(new GuiceServletConfig(injector)); - root.addFilter(GuiceFilter.class, "/druid/v2/datasources/*", 0); + root.addFilter(GuiceFilter.class, "/druid/v2/datasources/*", null); for (String path : pathsForGuiceFilter) { - root.addFilter(GuiceFilter.class, path, 0); + root.addFilter(GuiceFilter.class, path, null); } } diff --git a/client/src/main/java/com/metamx/druid/http/QueryServlet.java b/client/src/main/java/com/metamx/druid/http/QueryServlet.java index 8b871a49bcc..78cb428998a 100644 --- a/client/src/main/java/com/metamx/druid/http/QueryServlet.java +++ b/client/src/main/java/com/metamx/druid/http/QueryServlet.java @@ -33,9 +33,8 @@ import com.metamx.druid.query.segment.QuerySegmentWalker; import com.metamx.emitter.service.AlertEvent; import com.metamx.emitter.service.ServiceEmitter; import com.metamx.emitter.service.ServiceMetricEvent; - +import org.eclipse.jetty.server.Request; import org.joda.time.DateTime; -import org.mortbay.jetty.Request; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; diff --git a/client/src/main/java/com/metamx/druid/initialization/ConfigFactoryModule.java b/client/src/main/java/com/metamx/druid/initialization/ConfigModule.java similarity index 80% rename from client/src/main/java/com/metamx/druid/initialization/ConfigFactoryModule.java rename to client/src/main/java/com/metamx/druid/initialization/ConfigModule.java index 6d136c53da4..5d1245c23c2 100644 --- a/client/src/main/java/com/metamx/druid/initialization/ConfigFactoryModule.java +++ b/client/src/main/java/com/metamx/druid/initialization/ConfigModule.java @@ -23,19 +23,23 @@ import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Provides; import com.metamx.common.config.Config; +import com.metamx.druid.guice.JsonConfigurator; import com.metamx.druid.guice.LazySingleton; import org.skife.config.ConfigurationObjectFactory; +import javax.validation.Validation; +import javax.validation.Validator; import java.util.Properties; /** */ -public class ConfigFactoryModule implements Module +public class ConfigModule implements Module { @Override public void configure(Binder binder) { - + binder.bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator()); + binder.bind(JsonConfigurator.class).in(LazySingleton.class); } @Provides @LazySingleton diff --git a/client/src/main/java/com/metamx/druid/initialization/CuratorDiscoveryConfig.java b/client/src/main/java/com/metamx/druid/initialization/CuratorDiscoveryConfig.java index ee0f7ced76e..4fc6c28360e 100644 --- a/client/src/main/java/com/metamx/druid/initialization/CuratorDiscoveryConfig.java +++ b/client/src/main/java/com/metamx/druid/initialization/CuratorDiscoveryConfig.java @@ -23,7 +23,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** */ -public abstract class CuratorDiscoveryConfig +public class CuratorDiscoveryConfig { @JsonProperty private String path = null; diff --git a/client/src/main/java/com/metamx/druid/initialization/DruidNodeConfig.java b/client/src/main/java/com/metamx/druid/initialization/DruidNodeConfig.java index 94f02c5edd5..c0ab3491d4b 100644 --- a/client/src/main/java/com/metamx/druid/initialization/DruidNodeConfig.java +++ b/client/src/main/java/com/metamx/druid/initialization/DruidNodeConfig.java @@ -29,7 +29,7 @@ import javax.validation.constraints.NotNull; /** */ -public abstract class DruidNodeConfig +public class DruidNodeConfig { @NotNull private String serviceName = null; @@ -42,8 +42,8 @@ public abstract class DruidNodeConfig @JsonCreator public DruidNodeConfig( - @JsonProperty("service") String serviceName, @JsonProperty("host") String host, + @JsonProperty("service") String serviceName, @JsonProperty("port") Integer port ) { diff --git a/client/src/main/java/com/metamx/druid/initialization/EmitterModule.java b/client/src/main/java/com/metamx/druid/initialization/EmitterModule.java index 408358c2283..578f8e3ea16 100644 --- a/client/src/main/java/com/metamx/druid/initialization/EmitterModule.java +++ b/client/src/main/java/com/metamx/druid/initialization/EmitterModule.java @@ -19,6 +19,7 @@ package com.metamx.druid.initialization; +import com.google.common.base.Supplier; import com.google.common.collect.Lists; import com.google.inject.Binder; import com.google.inject.Binding; @@ -46,6 +47,7 @@ import java.util.Properties; public class EmitterModule implements Module { private static final Logger log = new Logger(EmitterModule.class); + private static final String EMITTER_PROPERTY = "druid.emitter"; private final Properties props; @@ -60,7 +62,7 @@ public class EmitterModule implements Module @Override public void configure(Binder binder) { - String emitterType = props.getProperty("druid.emitter", ""); + String emitterType = props.getProperty(EMITTER_PROPERTY, ""); binder.install(new LogEmitterModule()); binder.install(new HttpEmitterModule()); @@ -70,8 +72,9 @@ public class EmitterModule implements Module @Provides @LazySingleton - public ServiceEmitter getServiceEmitter(DruidNodeConfig config, Emitter emitter) + public ServiceEmitter getServiceEmitter(Supplier configSupplier, Emitter emitter) { + final DruidNodeConfig config = configSupplier.get(); final ServiceEmitter retVal = new ServiceEmitter(config.getServiceName(), config.getHost(), emitter); EmittingLogger.registerEmitter(retVal); return retVal; @@ -110,7 +113,7 @@ public class EmitterModule implements Module knownTypes.add(((Named) annotation).value()); } } - throw new ISE("Uknown emitter type, known types[%s]", knownTypes); + throw new ISE("Uknown emitter type[%s]=[%s], known types[%s]", EMITTER_PROPERTY, emitterType, knownTypes); } } diff --git a/client/src/main/java/com/metamx/druid/initialization/HttpEmitterConfig.java b/client/src/main/java/com/metamx/druid/initialization/HttpEmitterConfig.java index fd6955d3579..2a9467b3961 100644 --- a/client/src/main/java/com/metamx/druid/initialization/HttpEmitterConfig.java +++ b/client/src/main/java/com/metamx/druid/initialization/HttpEmitterConfig.java @@ -20,16 +20,16 @@ package com.metamx.druid.initialization; import com.fasterxml.jackson.annotation.JsonProperty; -import org.joda.time.Duration; +import org.joda.time.Period; /** */ -public abstract class HttpEmitterConfig extends com.metamx.emitter.core.HttpEmitterConfig +public class HttpEmitterConfig extends com.metamx.emitter.core.HttpEmitterConfig { @JsonProperty - private Duration timeOut = new Duration("PT5m"); + private Period timeOut = new Period("PT5M"); - public Duration getReadTimeout() + public Period getReadTimeout() { return timeOut; } diff --git a/client/src/main/java/com/metamx/druid/initialization/HttpEmitterModule.java b/client/src/main/java/com/metamx/druid/initialization/HttpEmitterModule.java index 8f7cc45018f..9f9c5eb5de0 100644 --- a/client/src/main/java/com/metamx/druid/initialization/HttpEmitterModule.java +++ b/client/src/main/java/com/metamx/druid/initialization/HttpEmitterModule.java @@ -24,6 +24,7 @@ import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Provides; import com.google.inject.name.Named; +import com.google.inject.util.Providers; import com.metamx.common.lifecycle.Lifecycle; import com.metamx.druid.guice.JsonConfigProvider; import com.metamx.druid.guice.LazySingleton; @@ -43,6 +44,9 @@ public class HttpEmitterModule implements Module public void configure(Binder binder) { JsonConfigProvider.bind(binder, "druid.emitter.http", HttpEmitterConfig.class); + + // Fix the injection of this if we want to enable ssl emission of events. + binder.bind(SSLContext.class).toProvider(Providers.of(null)).in(LazySingleton.class); } @Provides @LazySingleton @Named("http") @@ -51,7 +55,7 @@ public class HttpEmitterModule implements Module final HttpClientConfig.Builder builder = HttpClientConfig .builder() .withNumConnections(1) - .withReadTimeout(config.get().getReadTimeout()); + .withReadTimeout(config.get().getReadTimeout().toStandardDuration()); if (sslContext != null) { builder.withSslContext(sslContext); diff --git a/client/src/main/java/com/metamx/druid/initialization/Initialization.java b/client/src/main/java/com/metamx/druid/initialization/Initialization.java index 66366a3e739..faf7e5dbb65 100644 --- a/client/src/main/java/com/metamx/druid/initialization/Initialization.java +++ b/client/src/main/java/com/metamx/druid/initialization/Initialization.java @@ -21,8 +21,14 @@ package com.metamx.druid.initialization; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Charsets; +import com.google.common.base.Function; import com.google.common.base.Throwables; +import com.google.common.collect.Lists; import com.google.common.io.Closeables; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.metamx.common.ISE; import com.metamx.common.concurrent.ScheduledExecutorFactory; import com.metamx.common.config.Config; import com.metamx.common.lifecycle.Lifecycle; @@ -33,9 +39,12 @@ import com.metamx.druid.curator.discovery.AddressPortServiceInstanceFactory; import com.metamx.druid.curator.discovery.CuratorServiceAnnouncer; import com.metamx.druid.curator.discovery.ServiceAnnouncer; import com.metamx.druid.curator.discovery.ServiceInstanceFactory; +import com.metamx.druid.guice.DruidGuiceExtensions; +import com.metamx.druid.guice.DruidSecondaryModule; import com.metamx.druid.http.EmittingRequestLogger; import com.metamx.druid.http.FileRequestLogger; import com.metamx.druid.http.RequestLogger; +import com.metamx.druid.jackson.JacksonModule; import com.metamx.druid.utils.PropUtils; import com.metamx.emitter.core.Emitter; import org.apache.curator.framework.CuratorFramework; @@ -45,17 +54,20 @@ import org.apache.curator.x.discovery.ServiceDiscovery; import org.apache.curator.x.discovery.ServiceDiscoveryBuilder; import org.apache.curator.x.discovery.ServiceProvider; import org.apache.zookeeper.data.Stat; -import org.mortbay.jetty.Connector; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.nio.SelectChannelConnector; -import org.mortbay.thread.QueuedThreadPool; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.skife.config.ConfigurationObjectFactory; +import javax.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.List; import java.util.Properties; /** @@ -370,4 +382,46 @@ public class Initialization return new AddressPortServiceInstanceFactory(address, config.getPort()); } + + public static Injector makeInjector(final Object... modules) + { + final Injector baseInjector = Guice.createInjector( + new DruidGuiceExtensions(), + new JacksonModule(), + new PropertiesModule("runtime.properties"), + new ConfigModule() + ); + + List actualModules = Lists.newArrayList(); + + actualModules.add(DruidSecondaryModule.class); + actualModules.addAll(Arrays.asList(modules)); + + return Guice.createInjector( + Lists.transform( + actualModules, + new Function() + { + @Override + @SuppressWarnings("unchecked") + public Module apply(@Nullable Object input) + { + if (input instanceof Module) { + baseInjector.injectMembers(input); + return (Module) input; + } + if (input instanceof Class) { + if (Module.class.isAssignableFrom((Class) input)) { + return baseInjector.getInstance((Class) input); + } + else { + throw new ISE("Class[%s] does not implement %s", input.getClass(), Module.class); + } + } + throw new ISE("Unknown module type[%s]", input.getClass()); + } + } + ) + ); + } } diff --git a/client/src/main/java/com/metamx/druid/initialization/JettyServerInitializer.java b/client/src/main/java/com/metamx/druid/initialization/JettyServerInitializer.java new file mode 100644 index 00000000000..05b11c98e40 --- /dev/null +++ b/client/src/main/java/com/metamx/druid/initialization/JettyServerInitializer.java @@ -0,0 +1,11 @@ +package com.metamx.druid.initialization; + +import com.google.inject.Injector; +import org.eclipse.jetty.server.Server; + +/** + */ +public interface JettyServerInitializer +{ + public void initialize(Server server, Injector injector); +} diff --git a/client/src/main/java/com/metamx/druid/initialization/JettyServerModule.java b/client/src/main/java/com/metamx/druid/initialization/JettyServerModule.java new file mode 100644 index 00000000000..170c50396aa --- /dev/null +++ b/client/src/main/java/com/metamx/druid/initialization/JettyServerModule.java @@ -0,0 +1,62 @@ +package com.metamx.druid.initialization; + +import com.google.inject.Binder; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.metamx.common.lifecycle.Lifecycle; +import com.metamx.common.logger.Logger; +import com.metamx.druid.guice.ConfigProvider; +import com.metamx.druid.guice.LazySingleton; +import org.eclipse.jetty.server.Server; + +/** + */ +public class JettyServerModule implements Module +{ + private static final Logger log = new Logger(JettyServerModule.class); + + private final JettyServerInitializer initializer; + + public JettyServerModule( + JettyServerInitializer initializer + ) + { + this.initializer = initializer; + } + + @Override + public void configure(Binder binder) + { + ConfigProvider.bind(binder, ServerConfig.class); + } + + @Provides @LazySingleton + public Server getServer(Injector injector, Lifecycle lifecycle, ServerConfig config) + { + final Server server = Initialization.makeJettyServer(config); + initializer.initialize(server, injector); + lifecycle.addHandler( + new Lifecycle.Handler() + { + @Override + public void start() throws Exception + { + server.start(); + } + + @Override + public void stop() + { + try { + server.stop(); + } + catch (Exception e) { + log.warn(e, "Unable to stop Jetty server."); + } + } + } + ); + return server; + } +} diff --git a/common/pom.xml b/common/pom.xml index cfb8620e574..66538c62e6d 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -67,6 +67,10 @@ org.hibernate hibernate-validator + + javax.validation + validation-api + it.uniroma3.mat extendedset diff --git a/common/src/main/java/com/metamx/druid/config/ConfigManager.java b/common/src/main/java/com/metamx/druid/config/ConfigManager.java index 14b504a60ec..eb9bf67b476 100644 --- a/common/src/main/java/com/metamx/druid/config/ConfigManager.java +++ b/common/src/main/java/com/metamx/druid/config/ConfigManager.java @@ -1,5 +1,6 @@ package com.metamx.druid.config; +import com.google.common.base.Supplier; import com.google.common.base.Throwables; import com.google.common.collect.Maps; import com.google.inject.Inject; @@ -7,6 +8,7 @@ import com.metamx.common.concurrent.ScheduledExecutors; import com.metamx.common.lifecycle.LifecycleStart; import com.metamx.common.lifecycle.LifecycleStop; import com.metamx.common.logger.Logger; +import com.metamx.druid.db.DbTablesConfig; import org.joda.time.Duration; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.IDBI; @@ -34,7 +36,7 @@ public class ConfigManager private boolean started = false; private final IDBI dbi; - private final ConfigManagerConfig config; + private final Supplier config; private final ScheduledExecutorService exec; private final ConcurrentMap watchedConfigs; @@ -44,17 +46,20 @@ public class ConfigManager private volatile ConfigManager.PollingCallable poller; @Inject - public ConfigManager(IDBI dbi, ConfigManagerConfig config) // TODO: use DbTables and a different config + public ConfigManager(IDBI dbi, Supplier dbTables, Supplier config) { this.dbi = dbi; this.config = config; this.exec = ScheduledExecutors.fixed(1, "config-manager-%s"); this.watchedConfigs = Maps.newConcurrentMap(); - this.selectStatement = String.format("SELECT payload FROM %s WHERE name = :name", config.getConfigTable()); + + final String configTable = dbTables.get().getConfigTable(); + + this.selectStatement = String.format("SELECT payload FROM %s WHERE name = :name", configTable); insertStatement = String.format( "INSERT INTO %s (name, payload) VALUES (:name, :payload) ON DUPLICATE KEY UPDATE payload = :payload", - config.getConfigTable() + configTable ); } @@ -67,7 +72,9 @@ public class ConfigManager } poller = new PollingCallable(); - ScheduledExecutors.scheduleWithFixedDelay(exec, new Duration(0), config.getPollDuration(), poller); + ScheduledExecutors.scheduleWithFixedDelay( + exec, new Duration(0), config.get().getPollDuration().toStandardDuration(), poller + ); started = true; } diff --git a/common/src/main/java/com/metamx/druid/config/ConfigManagerConfig.java b/common/src/main/java/com/metamx/druid/config/ConfigManagerConfig.java index 94ab2eabd2a..b0eb7f5aa60 100644 --- a/common/src/main/java/com/metamx/druid/config/ConfigManagerConfig.java +++ b/common/src/main/java/com/metamx/druid/config/ConfigManagerConfig.java @@ -1,18 +1,20 @@ package com.metamx.druid.config; -import org.joda.time.Duration; -import org.skife.config.Config; -import org.skife.config.Default; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.joda.time.Period; + +import javax.validation.constraints.NotNull; /** */ -public abstract class ConfigManagerConfig +public class ConfigManagerConfig { - @Config("druid.database.configTable") - public abstract String getConfigTable(); - - @Config("druid.indexer.poll.duration") - @Default("PT1M") - public abstract Duration getPollDuration(); + @JsonProperty + @NotNull + private Period pollDuration = new Period("PT1M"); + public Period getPollDuration() + { + return pollDuration; + } } diff --git a/common/src/main/java/com/metamx/druid/config/ConfigManagerProvider.java b/common/src/main/java/com/metamx/druid/config/ConfigManagerProvider.java new file mode 100644 index 00000000000..032d2668152 --- /dev/null +++ b/common/src/main/java/com/metamx/druid/config/ConfigManagerProvider.java @@ -0,0 +1,74 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.metamx.druid.config; + +import com.google.common.base.Supplier; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.metamx.common.lifecycle.Lifecycle; +import com.metamx.druid.db.DbConnector; +import com.metamx.druid.db.DbTablesConfig; + +/** + */ +public class ConfigManagerProvider implements Provider +{ + private final DbConnector dbConnector; + private final Supplier dbTables; + private final Supplier config; + private final Lifecycle lifecycle; + + @Inject + ConfigManagerProvider( + DbConnector dbConnector, + Supplier dbTables, + Supplier config, + Lifecycle lifecycle + ) + { + this.dbConnector = dbConnector; + this.dbTables = dbTables; + this.config = config; + this.lifecycle = lifecycle; + } + + @Override + public ConfigManager get() + { + lifecycle.addHandler( + new Lifecycle.Handler() + { + @Override + public void start() throws Exception + { + dbConnector.createConfigTable(); + } + + @Override + public void stop() + { + + } + } + ); + + return new ConfigManager(dbConnector.getDBI(), dbTables, config); + } +} diff --git a/common/src/main/java/com/metamx/druid/db/DbConnector.java b/common/src/main/java/com/metamx/druid/db/DbConnector.java index 1cfc9904b09..f0c60bac43c 100644 --- a/common/src/main/java/com/metamx/druid/db/DbConnector.java +++ b/common/src/main/java/com/metamx/druid/db/DbConnector.java @@ -20,6 +20,7 @@ package com.metamx.druid.db; import com.google.common.base.Supplier; +import com.google.inject.Inject; import com.metamx.common.logger.Logger; import org.apache.commons.dbcp.BasicDataSource; import org.skife.jdbi.v2.DBI; @@ -165,6 +166,7 @@ public class DbConnector private final Supplier dbTables; private final DBI dbi; + @Inject public DbConnector(Supplier config, Supplier dbTables) { this.config = config; @@ -197,11 +199,32 @@ public class DbConnector public void createSegmentTable() { - createSegmentTable(dbi, dbTables.get().getSegmentsTable()); + if (config.get().isCreateTables()) { + createSegmentTable(dbi, dbTables.get().getSegmentsTable()); + } } public void createRulesTable() { - createRuleTable(dbi, dbTables.get().getRulesTable()); + if (config.get().isCreateTables()) { + createRuleTable(dbi, dbTables.get().getRulesTable()); + } + } + + public void createConfigTable() + { + if (config.get().isCreateTables()) { + createRuleTable(dbi, dbTables.get().getConfigTable()); + } + } + + public void createTaskTables() + { + if (config.get().isCreateTables()) { + final DbTablesConfig dbTablesConfig = dbTables.get(); + createTaskTable(dbi, dbTablesConfig.getTasksTable()); + createTaskLogTable(dbi, dbTablesConfig.getTaskLogTable()); + createTaskLockTable(dbi, dbTablesConfig.getTaskLockTable()); + } } } diff --git a/common/src/main/java/com/metamx/druid/db/DbConnectorConfig.java b/common/src/main/java/com/metamx/druid/db/DbConnectorConfig.java index f6e15bbcc48..bd9e15f669d 100644 --- a/common/src/main/java/com/metamx/druid/db/DbConnectorConfig.java +++ b/common/src/main/java/com/metamx/druid/db/DbConnectorConfig.java @@ -25,7 +25,7 @@ import javax.validation.constraints.NotNull; /** */ -public abstract class DbConnectorConfig +public class DbConnectorConfig { @JsonProperty private boolean createTables = true; diff --git a/common/src/main/java/com/metamx/druid/db/DbTablesConfig.java b/common/src/main/java/com/metamx/druid/db/DbTablesConfig.java index 96d7170f6fb..54567b3fe74 100644 --- a/common/src/main/java/com/metamx/druid/db/DbTablesConfig.java +++ b/common/src/main/java/com/metamx/druid/db/DbTablesConfig.java @@ -12,7 +12,7 @@ public class DbTablesConfig { public static DbTablesConfig fromBase(String base) { - return new DbTablesConfig(base, null, null); + return new DbTablesConfig(base, null, null, null, null, null, null); } @NotNull @@ -22,19 +22,38 @@ public class DbTablesConfig private final String segmentsTable; @NotNull - private final String ruleTable; + private final String rulesTable; + + @NotNull + private final String configTable; + + @NotNull + private final String tasksTable; + + @NotNull + private final String taskLogTable; + + @NotNull + private final String taskLockTable; @JsonCreator public DbTablesConfig( @JsonProperty("base") String base, @JsonProperty("segments") String segmentsTable, - @JsonProperty("rules") String rulesTable + @JsonProperty("rules") String rulesTable, + @JsonProperty("config") String configTable, + @JsonProperty("tasks") String tasksTable, + @JsonProperty("taskLog") String taskLogTable, + @JsonProperty("taskLock") String taskLockTable ) { - this.base = base; this.segmentsTable = makeTableName(segmentsTable, "segments"); - this.ruleTable = makeTableName(rulesTable, "rules"); + this.rulesTable = makeTableName(rulesTable, "rules"); + this.configTable = makeTableName(configTable, "config"); + this.tasksTable = makeTableName(tasksTable, "tasks"); + this.taskLogTable = makeTableName(taskLogTable, "task_log"); + this.taskLockTable = makeTableName(taskLockTable, "task_lock"); } private String makeTableName(String explicitTableName, String defaultSuffix) @@ -64,6 +83,30 @@ public class DbTablesConfig @JsonProperty("rules") public String getRulesTable() { - return ruleTable; + return rulesTable; + } + + @JsonProperty("config") + public String getConfigTable() + { + return configTable; + } + + @JsonProperty("tasks") + public String getTasksTable() + { + return tasksTable; + } + + @JsonProperty("taskLog") + public String getTaskLogTable() + { + return taskLogTable; + } + + @JsonProperty("taskLock") + public String getTaskLockTable() + { + return taskLockTable; } } \ No newline at end of file diff --git a/common/src/main/java/com/metamx/druid/guice/ConfigProvider.java b/common/src/main/java/com/metamx/druid/guice/ConfigProvider.java index 79eff1b41ff..d86bcbc04b7 100644 --- a/common/src/main/java/com/metamx/druid/guice/ConfigProvider.java +++ b/common/src/main/java/com/metamx/druid/guice/ConfigProvider.java @@ -4,15 +4,18 @@ import com.google.common.base.Preconditions; import com.google.inject.Binder; import com.google.inject.Inject; import com.google.inject.Provider; +import com.metamx.common.logger.Logger; import org.skife.config.ConfigurationObjectFactory; /** */ public class ConfigProvider implements Provider { + private static final Logger log = new Logger(ConfigProvider.class); + public static void bind(Binder binder, Class clazz) { - binder.bind(clazz).toProvider(of(clazz)).in(DruidScopes.SINGLETON); + binder.bind(clazz).toProvider(of(clazz)).in(LazySingleton.class); } public static Provider of(Class clazz) @@ -34,7 +37,13 @@ public class ConfigProvider implements Provider @Inject public void inject(ConfigurationObjectFactory factory) { - object = factory.build(clazz); + try { + object = factory.build(clazz); + } + catch (IllegalArgumentException e) { + log.info("Unable to build instance of class[%s]", clazz); + throw e; + } } @Override diff --git a/common/src/main/java/com/metamx/druid/guice/DruidSecondaryModule.java b/common/src/main/java/com/metamx/druid/guice/DruidSecondaryModule.java index da8d2ce59c1..43f54207652 100644 --- a/common/src/main/java/com/metamx/druid/guice/DruidSecondaryModule.java +++ b/common/src/main/java/com/metamx/druid/guice/DruidSecondaryModule.java @@ -8,6 +8,7 @@ import com.metamx.druid.jackson.Json; import com.metamx.druid.jackson.Smile; import org.skife.config.ConfigurationObjectFactory; +import javax.validation.Validator; import java.util.Properties; /** @@ -18,19 +19,25 @@ public class DruidSecondaryModule implements Module private final ConfigurationObjectFactory factory; private final ObjectMapper jsonMapper; private final ObjectMapper smileMapper; + private final Validator validator; + private final JsonConfigurator jsonConfigurator; @Inject public DruidSecondaryModule( Properties properties, ConfigurationObjectFactory factory, @Json ObjectMapper jsonMapper, - @Smile ObjectMapper smileMapper + @Smile ObjectMapper smileMapper, + Validator validator, + JsonConfigurator jsonConfigurator ) { this.properties = properties; this.factory = factory; this.jsonMapper = jsonMapper; this.smileMapper = smileMapper; + this.validator = validator; + this.jsonConfigurator = jsonConfigurator; } @Override @@ -41,5 +48,7 @@ public class DruidSecondaryModule implements Module binder.bind(ConfigurationObjectFactory.class).toInstance(factory); binder.bind(ObjectMapper.class).annotatedWith(Json.class).toInstance(jsonMapper); binder.bind(ObjectMapper.class).annotatedWith(Smile.class).toInstance(smileMapper); + binder.bind(Validator.class).toInstance(validator); + binder.bind(JsonConfigurator.class).toInstance(jsonConfigurator); } } diff --git a/common/src/main/java/com/metamx/druid/guice/JsonConfigProvider.java b/common/src/main/java/com/metamx/druid/guice/JsonConfigProvider.java index 64dd107d0f0..8c633060333 100644 --- a/common/src/main/java/com/metamx/druid/guice/JsonConfigProvider.java +++ b/common/src/main/java/com/metamx/druid/guice/JsonConfigProvider.java @@ -19,36 +19,26 @@ package com.metamx.druid.guice; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Joiner; import com.google.common.base.Supplier; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import com.google.common.base.Suppliers; import com.google.inject.Binder; import com.google.inject.Inject; +import com.google.inject.Key; import com.google.inject.Provider; -import com.google.inject.TypeLiteral; -import com.metamx.common.IAE; -import com.metamx.common.ISE; +import com.google.inject.util.Types; -import javax.validation.ConstraintViolation; -import javax.validation.Validator; -import java.io.IOException; -import java.util.List; -import java.util.Map; import java.util.Properties; -import java.util.Set; /** */ public class JsonConfigProvider implements Provider> { - - private static final Joiner JOINER = Joiner.on(", "); - + @SuppressWarnings("unchecked") public static void bind(Binder binder, String propertyBase, Class classToProvide) { - binder.bind(new TypeLiteral>(){}).toProvider(of(propertyBase, classToProvide)).in(DruidScopes.SINGLETON); + binder.bind(Key.get(Types.newParameterizedType(Supplier.class, classToProvide))) + .toProvider((Provider) of(propertyBase, classToProvide)) + .in(LazySingleton.class); } public static JsonConfigProvider of(String propertyBase, Class classToProvide) @@ -59,7 +49,8 @@ public class JsonConfigProvider implements Provider> private final String propertyBase; private final Class classToProvide; - private Supplier supplier; + private Properties props; + private JsonConfigurator configurator; public JsonConfigProvider( String propertyBase, @@ -73,49 +64,17 @@ public class JsonConfigProvider implements Provider> @Inject public void inject( Properties props, - ObjectMapper jsonMapper, - Validator validator + JsonConfigurator configurator ) { - Map jsonMap = Maps.newHashMap(); - for (String prop : props.stringPropertyNames()) { - if (prop.startsWith(propertyBase)) { - final String propValue = props.getProperty(prop); - try { - jsonMap.put(prop.substring(propertyBase.length()), jsonMapper.readValue(propValue, Object.class)); - } - catch (IOException e) { - throw new IAE("Unable to parse an object out of prop[%s]=[%s]", prop, propValue); - } - } - } - - final T config = jsonMapper.convertValue(jsonMap, classToProvide); - - final Set> violations = validator.validate(config); - if (!violations.isEmpty()) { - List messages = Lists.newArrayList(); - - for (ConstraintViolation violation : violations) { - messages.add(String.format("%s - %s", violation.getPropertyPath().toString(), violation.getMessage())); - } - - throw new ISE("Configuration violations[%s]", JOINER.join(messages)); - } - - this.supplier = new Supplier() - { - @Override - public T get() - { - return config; - } - }; + this.props = props; + this.configurator = configurator; } @Override public Supplier get() { - return supplier; + final T config = configurator.configurate(props, propertyBase, classToProvide); + return Suppliers.ofInstance(config); } } diff --git a/common/src/main/java/com/metamx/druid/guice/JsonConfigurator.java b/common/src/main/java/com/metamx/druid/guice/JsonConfigurator.java new file mode 100644 index 00000000000..2f35bed160b --- /dev/null +++ b/common/src/main/java/com/metamx/druid/guice/JsonConfigurator.java @@ -0,0 +1,94 @@ +package com.metamx.druid.guice; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.inject.Inject; +import com.google.inject.ProvisionException; +import com.google.inject.spi.Message; +import com.metamx.common.logger.Logger; + +import javax.annotation.Nullable; +import javax.validation.ConstraintViolation; +import javax.validation.Validator; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +/** + */ +public class JsonConfigurator +{ + private static final Logger log = new Logger(JsonConfigurator.class); + + private static final Joiner JOINER = Joiner.on("; "); + + private final ObjectMapper jsonMapper; + private final Validator validator; + + @Inject + public JsonConfigurator( + ObjectMapper jsonMapper, + Validator validator + ) + { + this.jsonMapper = jsonMapper; + this.validator = validator; + } + + public T configurate(Properties props, String propertyPrefix, Class clazz) throws ProvisionException + { + // Make it end with a period so we only include properties with sub-object thingies. + final String propertyBase = propertyPrefix.endsWith(".") ? propertyPrefix : propertyPrefix + "."; + + Map jsonMap = Maps.newHashMap(); + for (String prop : props.stringPropertyNames()) { + if (prop.startsWith(propertyBase)) { + final String propValue = props.getProperty(prop); + Object value; + try { + value = jsonMapper.readValue(propValue, Object.class); + } + catch (IOException e) { + log.debug("Unable to parse [%s]=[%s] as a json object, using as is.", prop, propValue); + value = propValue; + } + + jsonMap.put(prop.substring(propertyBase.length()), value); + } + } + + final T config = jsonMapper.convertValue(jsonMap, clazz); + + final Set> violations = validator.validate(config); + if (!violations.isEmpty()) { + List messages = Lists.newArrayList(); + + for (ConstraintViolation violation : violations) { + messages.add(String.format("%s - %s", violation.getPropertyPath().toString(), violation.getMessage())); + } + + throw new ProvisionException( + Iterables.transform( + messages, + new Function() + { + @Nullable + @Override + public Message apply(@Nullable String input) + { + return new Message(String.format("%s%s", propertyBase, input)); + } + } + ) + ); + } + + return config; + } +} diff --git a/examples/pom.xml b/examples/pom.xml index 0c5e000dddc..ff53f37e46a 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -29,99 +29,6 @@ ${project.parent.version} - - com.metamx - emitter - - - com.metamx - http-client - - - com.metamx - java-util - - - com.metamx - server-metrics - - - - com.davekoelle - alphanum - - - commons-codec - commons-codec - - - org.skife.config - config-magic - - - com.google.guava - guava - - - com.google.inject - guice - - - com.google.inject.extensions - guice-servlet - - - com.ibm.icu - icu4j - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.dataformat - jackson-dataformat-smile - - - org.jdbi - jdbi - - - com.sun.jersey - jersey-server - - - com.sun.jersey - jersey-core - - - com.sun.jersey.contribs - jersey-guice - - - org.mortbay.jetty - jetty - - - joda-time - joda-time - - - log4j - log4j - - - org.slf4j - slf4j-log4j12 - org.twitter4j twitter4j-core @@ -137,18 +44,6 @@ twitter4j-stream 2.2.6 - - - - junit - junit - test - - - org.easymock - easymock - test - diff --git a/indexing-service/pom.xml b/indexing-service/pom.xml index e3ff3e37803..b7ab5798382 100644 --- a/indexing-service/pom.xml +++ b/indexing-service/pom.xml @@ -145,8 +145,8 @@ jets3t - org.mortbay.jetty - jetty + org.eclipse.jetty + jetty-server joda-time diff --git a/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorNode.java b/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorNode.java index c98497a3602..5a6ac400d4c 100644 --- a/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorNode.java +++ b/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorNode.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.InjectableValues; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.smile.SmileFactory; import com.google.common.base.Optional; +import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; @@ -51,6 +52,7 @@ import com.metamx.druid.curator.discovery.ServiceAnnouncer; import com.metamx.druid.curator.discovery.ServiceInstanceFactory; import com.metamx.druid.db.DbConnector; import com.metamx.druid.db.DbConnectorConfig; +import com.metamx.druid.db.DbTablesConfig; import com.metamx.druid.http.GuiceServletConfig; import com.metamx.druid.http.RedirectFilter; import com.metamx.druid.http.RedirectInfo; @@ -115,18 +117,17 @@ import com.metamx.metrics.SysMonitor; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.PathChildrenCache; import org.apache.curator.x.discovery.ServiceDiscovery; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.resource.ResourceCollection; import org.jets3t.service.S3ServiceException; import org.jets3t.service.impl.rest.httpclient.RestS3Service; import org.jets3t.service.security.AWSCredentials; import org.joda.time.Duration; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.DefaultServlet; -import org.mortbay.jetty.servlet.FilterHolder; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.resource.ResourceCollection; import org.skife.config.ConfigurationObjectFactory; -import org.skife.jdbi.v2.IDBI; import java.io.IOException; import java.io.InputStream; @@ -153,7 +154,8 @@ public class IndexerCoordinatorNode extends QueryableNode monitors = null; private ServiceEmitter emitter = null; private DbConnectorConfig dbConnectorConfig = null; - private IDBI dbi = null; + private DbConnector dbi = null; + private Supplier dbTables = null; private IndexerCoordinatorConfig config = null; private MergerDBCoordinator mergerDBCoordinator = null; private ServiceDiscovery serviceDiscovery = null; @@ -238,19 +240,30 @@ public class IndexerCoordinatorNode extends QueryableNode getDbTables() + { + if (dbTables == null) { + dbTables = Suppliers.ofInstance( + getJsonConfigurator().configurate(getProps(), "druid.database.tables", DbTablesConfig.class) + ); + } + return dbTables; + } + public void doInit() throws Exception { final ScheduledExecutorFactory scheduledExecutorFactory = ScheduledExecutors.createFactory(getLifecycle()); initializeDB(); final ConfigManagerConfig managerConfig = getConfigFactory().build(ConfigManagerConfig.class); - DbConnector.createConfigTable(dbi, managerConfig.getConfigTable()); + dbi.createConfigTable(); JacksonConfigManager configManager = new JacksonConfigManager( getLifecycle().addManagedInstance( new ConfigManager( - dbi, - managerConfig + dbi.getDBI(), + getDbTables(), + Suppliers.ofInstance(managerConfig) ) ), getJsonMapper() ); @@ -296,7 +309,7 @@ public class IndexerCoordinatorNode extends QueryableNodeofInstance(dbConnectorConfig), null).getDBI() // TODO - ); + taskStorage = new DbTaskStorage(getJsonMapper(), dbConnectorConfig, dbi.getDBI()); } else { throw new ISE("Invalid storage implementation: %s", config.getStorageImpl()); } diff --git a/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorResource.java b/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorResource.java index e6f49b0d544..90837729306 100644 --- a/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorResource.java +++ b/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/IndexerCoordinatorResource.java @@ -41,10 +41,8 @@ import com.metamx.druid.indexing.coordinator.TaskQueue; import com.metamx.druid.indexing.coordinator.TaskRunner; import com.metamx.druid.indexing.coordinator.TaskRunnerWorkItem; import com.metamx.druid.indexing.coordinator.TaskStorageQueryAdapter; -import com.metamx.druid.indexing.coordinator.config.IndexerCoordinatorConfig; import com.metamx.druid.indexing.coordinator.scaling.ResourceManagementScheduler; import com.metamx.druid.indexing.coordinator.setup.WorkerSetupData; -import com.metamx.emitter.service.ServiceEmitter; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; @@ -89,8 +87,6 @@ public class IndexerCoordinatorResource } }; - private final IndexerCoordinatorConfig config; - private final ServiceEmitter emitter; private final TaskMasterLifecycle taskMasterLifecycle; private final TaskStorageQueryAdapter taskStorageQueryAdapter; private final TaskLogProvider taskLogProvider; @@ -101,8 +97,6 @@ public class IndexerCoordinatorResource @Inject public IndexerCoordinatorResource( - IndexerCoordinatorConfig config, - ServiceEmitter emitter, TaskMasterLifecycle taskMasterLifecycle, TaskStorageQueryAdapter taskStorageQueryAdapter, TaskLogProvider taskLogProvider, @@ -110,8 +104,6 @@ public class IndexerCoordinatorResource ObjectMapper jsonMapper ) throws Exception { - this.config = config; - this.emitter = emitter; this.taskMasterLifecycle = taskMasterLifecycle; this.taskStorageQueryAdapter = taskStorageQueryAdapter; this.taskLogProvider = taskLogProvider; diff --git a/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/OldIndexerCoordinatorResource.java b/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/OldIndexerCoordinatorResource.java index 36e7e948cd8..84897f424bd 100644 --- a/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/OldIndexerCoordinatorResource.java +++ b/indexing-service/src/main/java/com/metamx/druid/indexing/coordinator/http/OldIndexerCoordinatorResource.java @@ -6,8 +6,6 @@ import com.metamx.druid.config.JacksonConfigManager; import com.metamx.druid.indexing.common.tasklogs.TaskLogProvider; import com.metamx.druid.indexing.coordinator.TaskMasterLifecycle; import com.metamx.druid.indexing.coordinator.TaskStorageQueryAdapter; -import com.metamx.druid.indexing.coordinator.config.IndexerCoordinatorConfig; -import com.metamx.emitter.service.ServiceEmitter; import javax.ws.rs.Path; @@ -19,8 +17,6 @@ public class OldIndexerCoordinatorResource extends IndexerCoordinatorResource { @Inject public OldIndexerCoordinatorResource( - IndexerCoordinatorConfig config, - ServiceEmitter emitter, TaskMasterLifecycle taskMasterLifecycle, TaskStorageQueryAdapter taskStorageQueryAdapter, TaskLogProvider taskLogProvider, @@ -28,6 +24,6 @@ public class OldIndexerCoordinatorResource extends IndexerCoordinatorResource ObjectMapper jsonMapper ) throws Exception { - super(config, emitter, taskMasterLifecycle, taskStorageQueryAdapter, taskLogProvider, configManager, jsonMapper); + super(taskMasterLifecycle, taskStorageQueryAdapter, taskLogProvider, configManager, jsonMapper); } } diff --git a/indexing-service/src/main/java/com/metamx/druid/indexing/worker/executor/ExecutorNode.java b/indexing-service/src/main/java/com/metamx/druid/indexing/worker/executor/ExecutorNode.java index 6e0fa8b6fc3..2f3c1fbf4bb 100644 --- a/indexing-service/src/main/java/com/metamx/druid/indexing/worker/executor/ExecutorNode.java +++ b/indexing-service/src/main/java/com/metamx/druid/indexing/worker/executor/ExecutorNode.java @@ -77,13 +77,13 @@ import com.metamx.metrics.MonitorSchedulerConfig; import com.metamx.metrics.SysMonitor; import org.apache.curator.x.discovery.ServiceDiscovery; import org.apache.curator.x.discovery.ServiceProvider; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.jets3t.service.S3ServiceException; import org.jets3t.service.impl.rest.httpclient.RestS3Service; import org.jets3t.service.security.AWSCredentials; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.DefaultServlet; -import org.mortbay.jetty.servlet.ServletHolder; import org.skife.config.ConfigurationObjectFactory; import java.util.List; @@ -216,12 +216,12 @@ public class ExecutorNode extends BaseServerNode chatHandlerProvider ) ); - final Context root = new Context(server, "/", Context.SESSIONS); + final ServletContextHandler root = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); root.addServlet(new ServletHolder(new StatusServlet()), "/status"); root.addServlet(new ServletHolder(new DefaultServlet()), "/*"); root.addEventListener(new GuiceServletConfig(injector)); - root.addFilter(GuiceFilter.class, "/druid/worker/v1/*", 0); + root.addFilter(GuiceFilter.class, "/druid/worker/v1/*", null); root.addServlet( new ServletHolder( new QueryServlet(getJsonMapper(), getSmileMapper(), taskRunner, emitter, getRequestLogger()) diff --git a/indexing-service/src/main/java/com/metamx/druid/indexing/worker/http/WorkerNode.java b/indexing-service/src/main/java/com/metamx/druid/indexing/worker/http/WorkerNode.java index 2d69208cfd8..7b978d649e3 100644 --- a/indexing-service/src/main/java/com/metamx/druid/indexing/worker/http/WorkerNode.java +++ b/indexing-service/src/main/java/com/metamx/druid/indexing/worker/http/WorkerNode.java @@ -37,10 +37,6 @@ import com.metamx.druid.QueryableNode; import com.metamx.druid.curator.discovery.ServiceAnnouncer; import com.metamx.druid.http.GuiceServletConfig; import com.metamx.druid.http.StatusServlet; -import com.metamx.druid.initialization.CuratorDiscoveryConfig; -import com.metamx.druid.initialization.Initialization; -import com.metamx.druid.initialization.ServerConfig; -import com.metamx.druid.jackson.DefaultObjectMapper; import com.metamx.druid.indexing.common.config.IndexerZkConfig; import com.metamx.druid.indexing.common.config.TaskLogConfig; import com.metamx.druid.indexing.common.index.EventReceiverFirehoseFactory; @@ -54,6 +50,10 @@ import com.metamx.druid.indexing.worker.Worker; import com.metamx.druid.indexing.worker.WorkerCuratorCoordinator; import com.metamx.druid.indexing.worker.WorkerTaskMonitor; import com.metamx.druid.indexing.worker.config.WorkerConfig; +import com.metamx.druid.initialization.CuratorDiscoveryConfig; +import com.metamx.druid.initialization.Initialization; +import com.metamx.druid.initialization.ServerConfig; +import com.metamx.druid.jackson.DefaultObjectMapper; import com.metamx.druid.utils.PropUtils; import com.metamx.emitter.EmittingLogger; import com.metamx.emitter.core.Emitters; @@ -70,14 +70,14 @@ import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.PathChildrenCache; import org.apache.curator.x.discovery.ServiceDiscovery; import org.apache.curator.x.discovery.ServiceProvider; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.jets3t.service.S3ServiceException; import org.jets3t.service.impl.rest.httpclient.RestS3Service; import org.jets3t.service.security.AWSCredentials; import org.joda.time.Duration; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.DefaultServlet; -import org.mortbay.jetty.servlet.ServletHolder; import org.skife.config.ConfigurationObjectFactory; import java.util.List; @@ -204,12 +204,12 @@ public class WorkerNode extends QueryableNode forkingTaskRunner ) ); - final Context root = new Context(server, "/", Context.SESSIONS); + final ServletContextHandler root = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); root.addServlet(new ServletHolder(new StatusServlet()), "/status"); root.addServlet(new ServletHolder(new DefaultServlet()), "/*"); root.addEventListener(new GuiceServletConfig(injector)); - root.addFilter(GuiceFilter.class, "/druid/worker/v1/*", 0); + root.addFilter(GuiceFilter.class, "/druid/worker/v1/*", null); } @LifecycleStart diff --git a/pom.xml b/pom.xml index cae6b4b4c3c..b5767dcdbb6 100644 --- a/pom.xml +++ b/pom.xml @@ -230,6 +230,11 @@ hibernate-validator 5.0.1.Final + + javax.validation + validation-api + 1.1.0.Final + javax.inject javax.inject @@ -266,20 +271,19 @@ 0.8.1 - org.mortbay.jetty - jetty - 6.1.26 - - - org.mortbay.jetty - servlet-api - - + org.eclipse.jetty + jetty-server + 8.1.11.v20130520 - org.mortbay.jetty - jetty-util - 6.1.26 + org.eclipse.jetty + jetty-servlet + 8.1.11.v20130520 + + + org.eclipse.jetty + jetty-servlets + 8.1.11.v20130520 joda-time @@ -299,7 +303,7 @@ javax.servlet servlet-api - 2.5 + 3.0 org.slf4j diff --git a/realtime/pom.xml b/realtime/pom.xml index daf2dca271e..ca8b22f4de3 100644 --- a/realtime/pom.xml +++ b/realtime/pom.xml @@ -98,8 +98,8 @@ jets3t - org.mortbay.jetty - jetty + org.eclipse.jetty + jetty-server joda-time diff --git a/realtime/src/main/java/com/metamx/druid/realtime/RealtimeNode.java b/realtime/src/main/java/com/metamx/druid/realtime/RealtimeNode.java index c8d492d8716..4357f39c2b5 100644 --- a/realtime/src/main/java/com/metamx/druid/realtime/RealtimeNode.java +++ b/realtime/src/main/java/com/metamx/druid/realtime/RealtimeNode.java @@ -48,8 +48,8 @@ import com.metamx.druid.query.QueryRunnerFactoryConglomerate; import com.metamx.druid.utils.PropUtils; import com.metamx.emitter.service.ServiceEmitter; import com.metamx.metrics.Monitor; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.skife.config.ConfigurationObjectFactory; import java.io.File; @@ -148,7 +148,7 @@ public class RealtimeNode extends BaseServerNode startMonitoring(monitors); - final Context root = new Context(getServer(), "/", Context.SESSIONS); + final ServletContextHandler root = new ServletContextHandler(getServer(), "/", ServletContextHandler.SESSIONS); root.addServlet(new ServletHolder(new StatusServlet()), "/status"); root.addServlet( new ServletHolder( diff --git a/server/pom.xml b/server/pom.xml index be9fc9a2e7d..0ae6ac0560f 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -146,8 +146,8 @@ jets3t - org.mortbay.jetty - jetty + org.eclipse.jetty + jetty-server joda-time diff --git a/server/src/main/java/com/metamx/druid/db/DatabaseRuleManager.java b/server/src/main/java/com/metamx/druid/db/DatabaseRuleManager.java index 5e8550b0165..b308296fb31 100644 --- a/server/src/main/java/com/metamx/druid/db/DatabaseRuleManager.java +++ b/server/src/main/java/com/metamx/druid/db/DatabaseRuleManager.java @@ -118,7 +118,7 @@ public class DatabaseRuleManager private final ObjectMapper jsonMapper; private final ScheduledExecutorService exec; - private final DatabaseRuleManagerConfig config; + private final Supplier config; private final Supplier dbTables; private final IDBI dbi; private final AtomicReference>> rules; @@ -130,7 +130,7 @@ public class DatabaseRuleManager @Inject public DatabaseRuleManager( ObjectMapper jsonMapper, - DatabaseRuleManagerConfig config, + Supplier config, Supplier dbTables, IDBI dbi ) @@ -155,11 +155,11 @@ public class DatabaseRuleManager return; } - createDefaultRule(dbi, getRulesTable(), config.getDefaultTier(), jsonMapper); + createDefaultRule(dbi, getRulesTable(), config.get().getDefaultTier(), jsonMapper); ScheduledExecutors.scheduleWithFixedDelay( exec, new Duration(0), - config.getRulesPollDuration(), + config.get().getPollDuration().toStandardDuration(), new Runnable() { @Override @@ -267,8 +267,8 @@ public class DatabaseRuleManager if (theRules.get(dataSource) != null) { retVal.addAll(theRules.get(dataSource)); } - if (theRules.get(config.getDefaultTier()) != null) { - retVal.addAll(theRules.get(config.getDefaultTier())); + if (theRules.get(config.get().getDefaultTier()) != null) { + retVal.addAll(theRules.get(config.get().getDefaultTier())); } return retVal; } diff --git a/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerConfig.java b/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerConfig.java index 5f41945df58..8dfc0b83be1 100644 --- a/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerConfig.java +++ b/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerConfig.java @@ -19,19 +19,26 @@ package com.metamx.druid.db; -import org.joda.time.Duration; -import org.skife.config.Config; -import org.skife.config.Default; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.joda.time.Period; /** */ -public abstract class DatabaseRuleManagerConfig +public class DatabaseRuleManagerConfig { - @Config("druid.database.rules.defaultTier") - @Default("_default") - public abstract String getDefaultTier(); + @JsonProperty + private String defaultTier = "_default"; - @Config("druid.database.rules.poll.duration") - @Default("PT1M") - public abstract Duration getRulesPollDuration(); + @JsonProperty + private Period pollDuration = new Period("PT1M"); + + public String getDefaultTier() + { + return defaultTier; + } + + public Period getPollDuration() + { + return pollDuration; + } } diff --git a/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerProvider.java b/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerProvider.java new file mode 100644 index 00000000000..a2760068cc1 --- /dev/null +++ b/server/src/main/java/com/metamx/druid/db/DatabaseRuleManagerProvider.java @@ -0,0 +1,79 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.metamx.druid.db; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Supplier; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.metamx.common.lifecycle.Lifecycle; + +/** + */ +public class DatabaseRuleManagerProvider implements Provider +{ + private final ObjectMapper jsonMapper; + private final Supplier config; + private final Supplier dbTables; + private final DbConnector dbConnector; + private final Lifecycle lifecycle; + + @Inject + public DatabaseRuleManagerProvider( + ObjectMapper jsonMapper, + Supplier config, + Supplier dbTables, + DbConnector dbConnector, + Lifecycle lifecycle + ) + { + this.jsonMapper = jsonMapper; + this.config = config; + this.dbTables = dbTables; + this.dbConnector = dbConnector; + this.lifecycle = lifecycle; + } + + @Override + public DatabaseRuleManager get() + { + lifecycle.addHandler( + new Lifecycle.Handler() + { + @Override + public void start() throws Exception + { + dbConnector.createRulesTable(); + DatabaseRuleManager.createDefaultRule( + dbConnector.getDBI(), dbTables.get().getRulesTable(), config.get().getDefaultTier(), jsonMapper + ); + } + + @Override + public void stop() + { + + } + } + ); + + return new DatabaseRuleManager(jsonMapper, config, dbTables, dbConnector.getDBI()); + } +} diff --git a/server/src/main/java/com/metamx/druid/db/DatabaseSegmentManagerProvider.java b/server/src/main/java/com/metamx/druid/db/DatabaseSegmentManagerProvider.java new file mode 100644 index 00000000000..02abdbafb67 --- /dev/null +++ b/server/src/main/java/com/metamx/druid/db/DatabaseSegmentManagerProvider.java @@ -0,0 +1,81 @@ +/* + * Druid - a distributed column store. + * Copyright (C) 2012, 2013 Metamarkets Group Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package com.metamx.druid.db; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Supplier; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.metamx.common.lifecycle.Lifecycle; + +/** + */ +public class DatabaseSegmentManagerProvider implements Provider +{ + private final ObjectMapper jsonMapper; + private final Supplier config; + private final Supplier dbTables; + private final DbConnector dbConnector; + private final Lifecycle lifecycle; + + @Inject + public DatabaseSegmentManagerProvider( + ObjectMapper jsonMapper, + Supplier config, + Supplier dbTables, + DbConnector dbConnector, + Lifecycle lifecycle + ) + { + this.jsonMapper = jsonMapper; + this.config = config; + this.dbTables = dbTables; + this.dbConnector = dbConnector; + this.lifecycle = lifecycle; + } + + @Override + public DatabaseSegmentManager get() + { + lifecycle.addHandler( + new Lifecycle.Handler() + { + @Override + public void start() throws Exception + { + dbConnector.createSegmentTable(); + } + + @Override + public void stop() + { + + } + } + ); + + return new DatabaseSegmentManager( + jsonMapper, + config, + dbTables, + dbConnector.getDBI() + ); + } +} diff --git a/server/src/main/java/com/metamx/druid/guice/HttpClientModule.java b/server/src/main/java/com/metamx/druid/guice/HttpClientModule.java index 00ea9d01a7f..ac5eb18df16 100644 --- a/server/src/main/java/com/metamx/druid/guice/HttpClientModule.java +++ b/server/src/main/java/com/metamx/druid/guice/HttpClientModule.java @@ -1,6 +1,7 @@ package com.metamx.druid.guice; import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Supplier; import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Provides; @@ -26,7 +27,7 @@ public class HttpClientModule implements Module JsonConfigProvider.bind(binder, "druid.global.http", DruidHttpClientConfig.class); } - public abstract static class DruidHttpClientConfig + public static class DruidHttpClientConfig { @JsonProperty @Min(0) @@ -47,8 +48,14 @@ public class HttpClientModule implements Module } @Provides @LazySingleton @Global - public HttpClient makeHttpClient(DruidHttpClientConfig config, Lifecycle lifecycle, @Nullable SSLContext sslContext) + public HttpClient makeHttpClient( + Supplier configSupplier, + Lifecycle lifecycle, + @Nullable SSLContext sslContext + ) { + final DruidHttpClientConfig config = configSupplier.get(); + final HttpClientConfig.Builder builder = HttpClientConfig .builder() .withNumConnections(config.getNumConnections()) diff --git a/server/src/main/java/com/metamx/druid/guice/MasterModule.java b/server/src/main/java/com/metamx/druid/guice/MasterModule.java index 60d6ccbad6d..a791d2eb31e 100644 --- a/server/src/main/java/com/metamx/druid/guice/MasterModule.java +++ b/server/src/main/java/com/metamx/druid/guice/MasterModule.java @@ -1,9 +1,12 @@ package com.metamx.druid.guice; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.Provides; import com.google.inject.TypeLiteral; +import com.metamx.common.concurrent.ScheduledExecutorFactory; +import com.metamx.common.concurrent.ScheduledExecutors; import com.metamx.common.lifecycle.Lifecycle; import com.metamx.druid.client.ServerInventoryViewConfig; import com.metamx.druid.client.indexing.IndexingService; @@ -11,11 +14,25 @@ import com.metamx.druid.client.indexing.IndexingServiceClient; import com.metamx.druid.client.indexing.IndexingServiceSelector; import com.metamx.druid.client.selector.DiscoverySelector; import com.metamx.druid.client.selector.Server; +import com.metamx.druid.concurrent.Execs; +import com.metamx.druid.config.ConfigManager; +import com.metamx.druid.config.ConfigManagerConfig; +import com.metamx.druid.config.ConfigManagerProvider; +import com.metamx.druid.db.DatabaseRuleManager; +import com.metamx.druid.db.DatabaseRuleManagerConfig; +import com.metamx.druid.db.DatabaseRuleManagerProvider; +import com.metamx.druid.db.DatabaseSegmentManager; +import com.metamx.druid.db.DatabaseSegmentManagerConfig; +import com.metamx.druid.db.DatabaseSegmentManagerProvider; import com.metamx.druid.db.DbConnector; import com.metamx.druid.db.DbConnectorConfig; import com.metamx.druid.db.DbTablesConfig; +import com.metamx.druid.http.MasterRedirectInfo; +import com.metamx.druid.http.RedirectInfo; import com.metamx.druid.initialization.ZkPathsConfig; import com.metamx.druid.master.DruidMasterConfig; +import com.metamx.druid.master.LoadQueueTaskMaster; +import org.apache.curator.framework.CuratorFramework; import org.apache.curator.x.discovery.ServiceDiscovery; import org.apache.curator.x.discovery.ServiceProvider; import org.skife.jdbi.v2.IDBI; @@ -27,52 +44,58 @@ public class MasterModule implements Module @Override public void configure(Binder binder) { + ConfigProvider.bind(binder, DruidMasterConfig.class); ConfigProvider.bind(binder, ZkPathsConfig.class); ConfigProvider.bind(binder, ServerInventoryViewConfig.class); - ConfigProvider.bind(binder, DbConnectorConfig.class); - JsonConfigProvider.bind(binder, "druid.database.tables", DbTablesConfig.class); + JsonConfigProvider.bind(binder, "druid.db.tables", DbTablesConfig.class); + JsonConfigProvider.bind(binder, "druid.db.connector", DbConnectorConfig.class); + JsonConfigProvider.bind(binder, "druid.manager.config", ConfigManagerConfig.class); + JsonConfigProvider.bind(binder, "druid.manager.segment", DatabaseSegmentManagerConfig.class); + JsonConfigProvider.bind(binder, "druid.manager.rules", DatabaseRuleManagerConfig.class); + + binder.bind(DatabaseSegmentManager.class) + .toProvider(DatabaseSegmentManagerProvider.class) + .in(ManageLifecycle.class); + + binder.bind(DatabaseRuleManager.class) + .toProvider(DatabaseRuleManagerProvider.class) + .in(ManageLifecycle.class); + + binder.bind(ConfigManager.class) + .toProvider(ConfigManagerProvider.class) + .in(ManageLifecycle.class); binder.bind(new TypeLiteral>(){}) .annotatedWith(IndexingService.class) .to(IndexingServiceSelector.class) .in(ManageLifecycle.class); binder.bind(IndexingServiceClient.class).in(LazySingleton.class); + + binder.bind(RedirectInfo.class).to(MasterRedirectInfo.class).in(LazySingleton.class); } - @Provides @ManageLifecycle @IndexingService - public DiscoverySelector getIndexingServiceSelector(DruidMasterConfig config, ServiceDiscovery serviceDiscovery) + @Provides @LazySingleton @IndexingService + public ServiceProvider getServiceProvider(DruidMasterConfig config, ServiceDiscovery serviceDiscovery) { - final ServiceProvider serviceProvider = serviceDiscovery.serviceProviderBuilder() - .serviceName(config.getMergerServiceName()) - .build(); - - return new IndexingServiceSelector(serviceProvider); + return serviceDiscovery.serviceProviderBuilder().serviceName(config.getMergerServiceName()).build(); } @Provides @LazySingleton - public IDBI getDbi(final DbConnector dbConnector, final DbConnectorConfig config, Lifecycle lifecycle) + public IDBI getDbi(final DbConnector dbConnector) { - if (config.isCreateTables()) { - lifecycle.addHandler( - new Lifecycle.Handler() - { - @Override - public void start() throws Exception - { - dbConnector.createSegmentTable(); - dbConnector.createRulesTable(); - } - - @Override - public void stop() - { - - } - } - ); - } - return dbConnector.getDBI(); } + + @Provides @LazySingleton + public LoadQueueTaskMaster getLoadQueueTaskMaster(CuratorFramework curator, ObjectMapper jsonMapper) + { + return new LoadQueueTaskMaster(curator, jsonMapper, Execs.singleThreaded("Master-PeonExec--%d")); + } + + @Provides @LazySingleton + public ScheduledExecutorFactory getScheduledExecutorFactory(Lifecycle lifecycle) + { + return ScheduledExecutors.createFactory(lifecycle); + } } diff --git a/server/src/main/java/com/metamx/druid/http/ComputeNode.java b/server/src/main/java/com/metamx/druid/http/ComputeNode.java index f538b69b4db..5ffc6c234bc 100644 --- a/server/src/main/java/com/metamx/druid/http/ComputeNode.java +++ b/server/src/main/java/com/metamx/druid/http/ComputeNode.java @@ -38,19 +38,15 @@ import com.metamx.druid.initialization.Initialization; import com.metamx.druid.initialization.ServerInit; import com.metamx.druid.jackson.DefaultObjectMapper; import com.metamx.druid.loading.SegmentLoader; -import com.metamx.druid.loading.SegmentLoaderConfig; import com.metamx.druid.metrics.ServerMonitor; import com.metamx.druid.query.MetricsEmittingExecutorService; import com.metamx.druid.query.QueryRunnerFactoryConglomerate; -import com.metamx.druid.utils.PropUtils; import com.metamx.emitter.service.ServiceEmitter; import com.metamx.emitter.service.ServiceMetricEvent; import com.metamx.metrics.Monitor; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; import org.jets3t.service.S3ServiceException; -import org.jets3t.service.impl.rest.httpclient.RestS3Service; -import org.jets3t.service.security.AWSCredentials; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHolder; import org.skife.config.ConfigurationObjectFactory; import java.util.List; @@ -128,7 +124,7 @@ public class ComputeNode extends BaseServerNode monitors.add(new ServerMonitor(getDruidServerMetadata(), serverManager)); startMonitoring(monitors); - final Context root = new Context(getServer(), "/", Context.SESSIONS); + final ServletContextHandler root = new ServletContextHandler(getServer(), "/", ServletContextHandler.SESSIONS); root.addServlet(new ServletHolder(new StatusServlet()), "/status"); root.addServlet( new ServletHolder( diff --git a/server/src/main/java/com/metamx/druid/http/MasterMain.java b/server/src/main/java/com/metamx/druid/http/MasterMain.java index 12c2a87dc7f..f4c3841f1a1 100644 --- a/server/src/main/java/com/metamx/druid/http/MasterMain.java +++ b/server/src/main/java/com/metamx/druid/http/MasterMain.java @@ -19,67 +19,33 @@ package com.metamx.druid.http; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Function; -import com.google.common.base.Throwables; -import com.google.common.collect.Lists; -import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; -import com.google.inject.Module; import com.google.inject.servlet.GuiceFilter; -import com.metamx.common.ISE; -import com.metamx.common.concurrent.ScheduledExecutorFactory; -import com.metamx.common.concurrent.ScheduledExecutors; import com.metamx.common.lifecycle.Lifecycle; import com.metamx.common.logger.Logger; -import com.metamx.druid.client.ServerInventoryView; -import com.metamx.druid.client.indexing.IndexingServiceClient; -import com.metamx.druid.concurrent.Execs; -import com.metamx.druid.config.ConfigManager; -import com.metamx.druid.config.ConfigManagerConfig; -import com.metamx.druid.config.JacksonConfigManager; import com.metamx.druid.curator.CuratorModule; import com.metamx.druid.curator.discovery.DiscoveryModule; import com.metamx.druid.curator.discovery.ServiceAnnouncer; -import com.metamx.druid.db.DatabaseRuleManager; -import com.metamx.druid.db.DatabaseSegmentManager; -import com.metamx.druid.db.DbConnector; -import com.metamx.druid.guice.DruidGuiceExtensions; -import com.metamx.druid.guice.DruidSecondaryModule; import com.metamx.druid.guice.HttpClientModule; import com.metamx.druid.guice.LifecycleModule; import com.metamx.druid.guice.MasterModule; import com.metamx.druid.guice.ServerModule; -import com.metamx.druid.initialization.ConfigFactoryModule; import com.metamx.druid.initialization.DruidNodeConfig; import com.metamx.druid.initialization.EmitterModule; import com.metamx.druid.initialization.Initialization; -import com.metamx.druid.initialization.PropertiesModule; -import com.metamx.druid.initialization.ServerConfig; -import com.metamx.druid.initialization.ZkPathsConfig; -import com.metamx.druid.jackson.JacksonModule; +import com.metamx.druid.initialization.JettyServerInitializer; +import com.metamx.druid.initialization.JettyServerModule; import com.metamx.druid.log.LogLevelAdjuster; import com.metamx.druid.master.DruidMaster; -import com.metamx.druid.master.DruidMasterConfig; -import com.metamx.druid.master.LoadQueueTaskMaster; import com.metamx.druid.metrics.MetricsModule; -import com.metamx.emitter.service.ServiceEmitter; import com.metamx.metrics.MonitorScheduler; -import org.apache.curator.framework.CuratorFramework; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.DefaultServlet; -import org.mortbay.jetty.servlet.FilterHolder; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.servlet.GzipFilter; -import org.skife.config.ConfigurationObjectFactory; -import org.skife.jdbi.v2.IDBI; - -import javax.annotation.Nullable; -import java.net.URL; -import java.util.Arrays; -import java.util.List; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.servlets.GzipFilter; /** */ @@ -91,185 +57,55 @@ public class MasterMain { LogLevelAdjuster.register(); - Injector injector = makeInjector( - new LifecycleModule(Key.get(MonitorScheduler.class)), + Injector injector = Initialization.makeInjector( + new LifecycleModule(Key.get(MonitorScheduler.class), Key.get(DruidMaster.class)), EmitterModule.class, HttpClientModule.class, CuratorModule.class, - MetricsModule.class, + new MetricsModule(), DiscoveryModule.class, ServerModule.class, + new JettyServerModule(new MasterJettyServerInitializer()), MasterModule.class ); - final ObjectMapper jsonMapper = injector.getInstance(ObjectMapper.class); - final ConfigurationObjectFactory configFactory = injector.getInstance(ConfigurationObjectFactory.class); final Lifecycle lifecycle = injector.getInstance(Lifecycle.class); - final ServiceEmitter emitter = injector.getInstance(ServiceEmitter.class); - - final ScheduledExecutorFactory scheduledExecutorFactory = ScheduledExecutors.createFactory(lifecycle); - - CuratorFramework curatorFramework = injector.getInstance(CuratorFramework.class); - - final ZkPathsConfig zkPaths = configFactory.build(ZkPathsConfig.class); - - ServerInventoryView serverInventoryView = injector.getInstance(ServerInventoryView.class); - - - final DatabaseSegmentManager databaseSegmentManager = injector.getInstance(DatabaseSegmentManager.class); - final DatabaseRuleManager databaseRuleManager = injector.getInstance(DatabaseRuleManager.class); - - final DruidMasterConfig druidMasterConfig = configFactory.build(DruidMasterConfig.class); - final DruidNodeConfig nodeConfig = configFactory.build(DruidNodeConfig.class); + final DruidNodeConfig nodeConfig = injector.getInstance(DruidNodeConfig.class); final ServiceAnnouncer serviceAnnouncer = injector.getInstance(ServiceAnnouncer.class); - Initialization.announceDefaultService(nodeConfig, serviceAnnouncer, lifecycle); - - IDBI dbi = injector.getInstance(IDBI.class); // TODO: make tables and stuff - final ConfigManagerConfig configManagerConfig = configFactory.build(ConfigManagerConfig.class); - DbConnector.createConfigTable(dbi, configManagerConfig.getConfigTable()); - JacksonConfigManager configManager = new JacksonConfigManager( - new ConfigManager(dbi, configManagerConfig), jsonMapper - ); - - final LoadQueueTaskMaster taskMaster = new LoadQueueTaskMaster( - curatorFramework, jsonMapper, Execs.singleThreaded("Master-PeonExec--%d") - ); - - final DruidMaster master = new DruidMaster( - druidMasterConfig, - zkPaths, - configManager, - databaseSegmentManager, - serverInventoryView, - databaseRuleManager, - curatorFramework, - emitter, - scheduledExecutorFactory, - injector.getInstance(IndexingServiceClient.class), - taskMaster - ); - lifecycle.addManagedInstance(master); try { lifecycle.start(); + + Initialization.announceDefaultService(nodeConfig, serviceAnnouncer, lifecycle); } catch (Throwable t) { log.error(t, "Error when starting up. Failing."); System.exit(1); } - Runtime.getRuntime().addShutdownHook( - new Thread( - new Runnable() - { - @Override - public void run() - { - log.info("Running shutdown hook"); - lifecycle.stop(); - } - } - ) - ); - - final Server server = Initialization.makeJettyServer(configFactory.build(ServerConfig.class)); - - final RedirectInfo redirectInfo = new RedirectInfo() - { - @Override - public boolean doLocal() - { - return master.isClusterMaster(); - } - - @Override - public URL getRedirectURL(String queryString, String requestURI) - { - try { - final String currentMaster = master.getCurrentMaster(); - if (currentMaster == null) { - return null; - } - - String location = String.format("http://%s%s", currentMaster, requestURI); - - if (queryString != null) { - location = String.format("%s?%s", location, queryString); - } - - return new URL(location); - } - catch (Exception e) { - throw Throwables.propagate(e); - } - } - }; - - final Context staticContext = new Context(server, "/static", Context.SESSIONS); - staticContext.addServlet(new ServletHolder(new RedirectServlet(redirectInfo)), "/*"); - - staticContext.setResourceBase(ComputeMain.class.getClassLoader().getResource("static").toExternalForm()); - - final Context root = new Context(server, "/", Context.SESSIONS); - root.addServlet(new ServletHolder(new StatusServlet()), "/status"); - root.addServlet(new ServletHolder(new DefaultServlet()), "/*"); - root.addEventListener(new GuiceServletConfig(injector)); - root.addFilter(GzipFilter.class, "/*", 0); - root.addFilter( - new FilterHolder( - new RedirectFilter( - redirectInfo - ) - ), "/*", 0 - ); - root.addFilter(GuiceFilter.class, "/info/*", 0); - root.addFilter(GuiceFilter.class, "/master/*", 0); - - server.start(); - server.join(); + lifecycle.join(); } - private static Injector makeInjector(final Object... modules) + private static class MasterJettyServerInitializer implements JettyServerInitializer { - final Injector baseInjector = Guice.createInjector( - new DruidGuiceExtensions(), - new JacksonModule(), - new PropertiesModule("runtime.properties"), - new ConfigFactoryModule() - ); + @Override + public void initialize(Server server, Injector injector) + { + final ServletContextHandler staticContext = new ServletContextHandler(server, "/static", ServletContextHandler.SESSIONS); + staticContext.addServlet(new ServletHolder(injector.getInstance(RedirectServlet.class)), "/*"); - List actualModules = Lists.newArrayList(); + staticContext.setResourceBase(ComputeMain.class.getClassLoader().getResource("static").toExternalForm()); - actualModules.add(DruidSecondaryModule.class); - actualModules.addAll(Arrays.asList(modules)); - - return Guice.createInjector( - Lists.transform( - actualModules, - new Function() - { - @Override - @SuppressWarnings("unchecked") - public Module apply(@Nullable Object input) - { - if (input instanceof Module) { - baseInjector.injectMembers(input); - return (Module) input; - } - if (input instanceof Class) { - if (Module.class.isAssignableFrom((Class) input)) { - return baseInjector.getInstance((Class) input); - } - else { - throw new ISE("Class[%s] does not implement %s", input.getClass(), Module.class); - } - } - throw new ISE("Unknown module type[%s]", input.getClass()); - } - } - ) - ); + final ServletContextHandler root = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); + root.addServlet(new ServletHolder(new StatusServlet()), "/status"); + root.addServlet(new ServletHolder(new DefaultServlet()), "/*"); + root.addEventListener(new GuiceServletConfig(injector)); + root.addFilter(GzipFilter.class, "/*", null); + root.addFilter(new FilterHolder(injector.getInstance(RedirectFilter.class)), "/*", null); + root.addFilter(GuiceFilter.class, "/info/*", null); + root.addFilter(GuiceFilter.class, "/master/*", null); + } } } diff --git a/server/src/main/java/com/metamx/druid/http/MasterRedirectInfo.java b/server/src/main/java/com/metamx/druid/http/MasterRedirectInfo.java new file mode 100644 index 00000000000..f3c263682df --- /dev/null +++ b/server/src/main/java/com/metamx/druid/http/MasterRedirectInfo.java @@ -0,0 +1,47 @@ +package com.metamx.druid.http; + +import com.google.common.base.Throwables; +import com.google.inject.Inject; +import com.metamx.druid.master.DruidMaster; + +import java.net.URL; + +/** +*/ +public class MasterRedirectInfo implements RedirectInfo +{ + private final DruidMaster master; + + @Inject + public MasterRedirectInfo(DruidMaster master) { + this.master = master; + } + + @Override + public boolean doLocal() + { + return master.isClusterMaster(); + } + + @Override + public URL getRedirectURL(String queryString, String requestURI) + { + try { + final String currentMaster = master.getCurrentMaster(); + if (currentMaster == null) { + return null; + } + + String location = String.format("http://%s%s", currentMaster, requestURI); + + if (queryString != null) { + location = String.format("%s?%s", location, queryString); + } + + return new URL(location); + } + catch (Exception e) { + throw Throwables.propagate(e); + } + } +} diff --git a/server/src/main/java/com/metamx/druid/http/RedirectFilter.java b/server/src/main/java/com/metamx/druid/http/RedirectFilter.java index 9a1a3c66bd3..5ed2bff98ee 100644 --- a/server/src/main/java/com/metamx/druid/http/RedirectFilter.java +++ b/server/src/main/java/com/metamx/druid/http/RedirectFilter.java @@ -19,6 +19,7 @@ package com.metamx.druid.http; +import com.google.inject.Inject; import com.metamx.common.logger.Logger; import javax.servlet.Filter; @@ -40,6 +41,7 @@ public class RedirectFilter implements Filter private final RedirectInfo redirectInfo; + @Inject public RedirectFilter( RedirectInfo redirectInfo ) diff --git a/server/src/main/java/com/metamx/druid/http/RedirectServlet.java b/server/src/main/java/com/metamx/druid/http/RedirectServlet.java index 2befa9cd458..7b4ad2aec53 100644 --- a/server/src/main/java/com/metamx/druid/http/RedirectServlet.java +++ b/server/src/main/java/com/metamx/druid/http/RedirectServlet.java @@ -19,6 +19,7 @@ package com.metamx.druid.http; +import com.google.inject.Inject; import com.metamx.common.logger.Logger; import org.mortbay.jetty.servlet.DefaultServlet; @@ -38,6 +39,7 @@ public class RedirectServlet extends DefaultServlet private final RedirectInfo redirectInfo; + @Inject public RedirectServlet( RedirectInfo redirectInfo ) diff --git a/server/src/main/java/com/metamx/druid/master/DruidMaster.java b/server/src/main/java/com/metamx/druid/master/DruidMaster.java index c3800e87bba..2a5f5a77fa3 100644 --- a/server/src/main/java/com/metamx/druid/master/DruidMaster.java +++ b/server/src/main/java/com/metamx/druid/master/DruidMaster.java @@ -28,6 +28,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.io.Closeables; +import com.google.inject.Inject; import com.metamx.common.Pair; import com.metamx.common.concurrent.ScheduledExecutorFactory; import com.metamx.common.concurrent.ScheduledExecutors; @@ -44,6 +45,7 @@ import com.metamx.druid.concurrent.Execs; import com.metamx.druid.config.JacksonConfigManager; import com.metamx.druid.db.DatabaseRuleManager; import com.metamx.druid.db.DatabaseSegmentManager; +import com.metamx.druid.guice.ManageLifecycle; import com.metamx.druid.index.v1.IndexIO; import com.metamx.druid.initialization.ZkPathsConfig; import com.metamx.emitter.EmittingLogger; @@ -68,6 +70,7 @@ import java.util.concurrent.atomic.AtomicReference; /** */ +@ManageLifecycle public class DruidMaster { public static final String MASTER_OWNER_NODE = "_MASTER"; @@ -94,6 +97,7 @@ public class DruidMaster private final Map loadManagementPeons; private final AtomicReference leaderLatch; + @Inject public DruidMaster( DruidMasterConfig config, ZkPathsConfig zkPaths, diff --git a/server/src/main/java/com/metamx/druid/master/LoadQueueTaskMaster.java b/server/src/main/java/com/metamx/druid/master/LoadQueueTaskMaster.java index 9ef5b61e5a0..eecdbacef30 100644 --- a/server/src/main/java/com/metamx/druid/master/LoadQueueTaskMaster.java +++ b/server/src/main/java/com/metamx/druid/master/LoadQueueTaskMaster.java @@ -20,6 +20,7 @@ package com.metamx.druid.master; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.inject.Inject; import org.apache.curator.framework.CuratorFramework; import java.util.concurrent.ExecutorService; @@ -33,6 +34,7 @@ public class LoadQueueTaskMaster private final ObjectMapper jsonMapper; private final ExecutorService peonExec; + @Inject public LoadQueueTaskMaster( CuratorFramework curator, ObjectMapper jsonMapper, diff --git a/server/src/main/java/com/metamx/druid/metrics/DruidMonitorSchedulerConfig.java b/server/src/main/java/com/metamx/druid/metrics/DruidMonitorSchedulerConfig.java new file mode 100644 index 00000000000..68d70738cca --- /dev/null +++ b/server/src/main/java/com/metamx/druid/metrics/DruidMonitorSchedulerConfig.java @@ -0,0 +1,26 @@ +package com.metamx.druid.metrics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.metamx.metrics.MonitorSchedulerConfig; +import org.joda.time.Duration; +import org.joda.time.Period; + +/** + */ +public class DruidMonitorSchedulerConfig extends MonitorSchedulerConfig +{ + @JsonProperty + private Period emissionPeriod = new Period("PT1M"); + + @JsonProperty + public Period getEmissionPeriod() + { + return emissionPeriod; + } + + @Override + public Duration getEmitterPeriod() + { + return emissionPeriod.toStandardDuration(); + } +} diff --git a/server/src/main/java/com/metamx/druid/metrics/MetricsModule.java b/server/src/main/java/com/metamx/druid/metrics/MetricsModule.java index 610514bcc39..28e68c7c17b 100644 --- a/server/src/main/java/com/metamx/druid/metrics/MetricsModule.java +++ b/server/src/main/java/com/metamx/druid/metrics/MetricsModule.java @@ -1,5 +1,6 @@ package com.metamx.druid.metrics; +import com.google.common.base.Supplier; import com.google.common.collect.Lists; import com.google.inject.Binder; import com.google.inject.Injector; @@ -8,13 +9,13 @@ import com.google.inject.Module; import com.google.inject.Provides; import com.metamx.common.logger.Logger; import com.metamx.druid.concurrent.Execs; +import com.metamx.druid.guice.JsonConfigProvider; import com.metamx.druid.guice.LazySingleton; import com.metamx.druid.guice.ManageLifecycle; import com.metamx.emitter.service.ServiceEmitter; import com.metamx.metrics.JvmMonitor; import com.metamx.metrics.Monitor; import com.metamx.metrics.MonitorScheduler; -import com.metamx.metrics.MonitorSchedulerConfig; import com.metamx.metrics.SysMonitor; import java.util.List; @@ -44,8 +45,10 @@ public class MetricsModule implements Module @Override public void configure(Binder binder) { + JsonConfigProvider.bind(binder, "druid.monitoring", DruidMonitorSchedulerConfig.class); + binder.bind(JvmMonitor.class).in(LazySingleton.class); - binder.bind(SysMonitor.class).in(LazySingleton.class); + binder.bind(SysMonitor.class).in(LazySingleton.class); // TODO: allow for disabling of this monitor for (Class monitor : monitors) { binder.bind(monitor).in(LazySingleton.class); @@ -53,7 +56,11 @@ public class MetricsModule implements Module } @Provides @ManageLifecycle - public MonitorScheduler getMonitorScheduler(MonitorSchedulerConfig config, ServiceEmitter emitter, Injector injector) + public MonitorScheduler getMonitorScheduler( + Supplier config, + ServiceEmitter emitter, + Injector injector + ) { List monitors = Lists.newArrayList(); @@ -68,7 +75,7 @@ public class MetricsModule implements Module } return new MonitorScheduler( - config, + config.get(), Execs.scheduledSingleThreaded("MonitorScheduler-%s"), emitter, monitors