Merge pull request #242 from metamx/guice

Druid version 0.6.0
This commit is contained in:
fjy 2013-09-18 16:00:08 -07:00
commit a74b6de9c5
1152 changed files with 32644 additions and 16908 deletions

3
.gitignore vendored
View File

@ -10,7 +10,6 @@ target
.idea
.project
.settings/
examples/rand/RealtimeNode.out
examples/twitter/RealtimeNode.out
*.log
*.DS_Store
_site

View File

@ -1,243 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Druid - a distributed column store.
~ Copyright (C) 2012 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.metamx.druid</groupId>
<artifactId>druid-client</artifactId>
<name>druid-client</name>
<description>druid-client</description>
<parent>
<groupId>com.metamx</groupId>
<artifactId>druid</artifactId>
<version>0.5.59-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.metamx.druid</groupId>
<artifactId>druid-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.metamx.druid</groupId>
<artifactId>druid-indexing-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.metamx</groupId>
<artifactId>emitter</artifactId>
</dependency>
<dependency>
<groupId>com.metamx</groupId>
<artifactId>http-client</artifactId>
</dependency>
<dependency>
<groupId>com.metamx</groupId>
<artifactId>java-util</artifactId>
</dependency>
<dependency>
<groupId>com.metamx</groupId>
<artifactId>server-metrics</artifactId>
</dependency>
<dependency>
<groupId>com.davekoelle</groupId>
<artifactId>alphanum</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.skife.config</groupId>
<artifactId>config-magic</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-guice</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.4.Final</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>spymemcached</artifactId>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<dependency>
<groupId>com.metamx</groupId>
<artifactId>bytebuffer-collections</artifactId>
</dependency>
<dependency>
<groupId>net.jpountz.lz4</groupId>
<artifactId>lz4</artifactId>
</dependency>
<!-- Tests -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.caliper</groupId>
<artifactId>caliper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,618 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.metamx.common.IAE;
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.lifecycle.LifecycleStart;
import com.metamx.common.lifecycle.LifecycleStop;
import com.metamx.common.logger.Logger;
import com.metamx.druid.client.BatchServerInventoryView;
import com.metamx.druid.client.DruidServerConfig;
import com.metamx.druid.client.InventoryView;
import com.metamx.druid.client.ServerInventoryView;
import com.metamx.druid.client.ServerInventoryViewConfig;
import com.metamx.druid.client.ServerView;
import com.metamx.druid.client.SingleServerInventoryView;
import com.metamx.druid.concurrent.Execs;
import com.metamx.druid.coordination.AbstractDataSegmentAnnouncer;
import com.metamx.druid.coordination.BatchDataSegmentAnnouncer;
import com.metamx.druid.coordination.DataSegmentAnnouncer;
import com.metamx.druid.coordination.DruidServerMetadata;
import com.metamx.druid.coordination.MultipleDataSegmentAnnouncerDataSegmentAnnouncer;
import com.metamx.druid.coordination.SingleDataSegmentAnnouncer;
import com.metamx.druid.curator.announcement.Announcer;
import com.metamx.druid.http.NoopRequestLogger;
import com.metamx.druid.http.RequestLogger;
import com.metamx.druid.initialization.CuratorConfig;
import com.metamx.druid.initialization.Initialization;
import com.metamx.druid.initialization.ServerConfig;
import com.metamx.druid.initialization.ZkDataSegmentAnnouncerConfig;
import com.metamx.druid.initialization.ZkPathsConfig;
import com.metamx.druid.utils.PropUtils;
import com.metamx.emitter.EmittingLogger;
import com.metamx.emitter.core.Emitters;
import com.metamx.emitter.service.ServiceEmitter;
import com.metamx.http.client.HttpClient;
import com.metamx.http.client.HttpClientConfig;
import com.metamx.http.client.HttpClientInit;
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 org.apache.curator.framework.CuratorFramework;
import org.joda.time.Duration;
import org.mortbay.jetty.Server;
import org.skife.config.ConfigurationObjectFactory;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
/**
*/
public abstract class QueryableNode<T extends QueryableNode> extends RegisteringNode
{
private final Logger log;
private final Lifecycle lifecycle;
private final ObjectMapper jsonMapper;
private final ObjectMapper smileMapper;
private final Properties props;
private final ConfigurationObjectFactory configFactory;
private final String nodeType;
private DruidServerMetadata druidServerMetadata = null;
private ServiceEmitter emitter = null;
private List<Monitor> monitors = null;
private Server server = null;
private CuratorFramework curator = null;
private DataSegmentAnnouncer announcer = null;
private ZkPathsConfig zkPaths = null;
private ScheduledExecutorFactory scheduledExecutorFactory = null;
private RequestLogger requestLogger = null;
private ServerInventoryView serverInventoryView = null;
private ServerView serverView = null;
private InventoryView inventoryView = null;
private boolean initialized = false;
public QueryableNode(
String nodeType,
Logger log,
Properties props,
Lifecycle lifecycle,
ObjectMapper jsonMapper,
ObjectMapper smileMapper,
ConfigurationObjectFactory configFactory
)
{
super(Arrays.asList(jsonMapper, smileMapper));
this.log = log;
this.configFactory = configFactory;
this.props = props;
this.jsonMapper = jsonMapper;
this.lifecycle = lifecycle;
this.smileMapper = smileMapper;
Preconditions.checkNotNull(props, "props");
Preconditions.checkNotNull(lifecycle, "lifecycle");
Preconditions.checkNotNull(jsonMapper, "jsonMapper");
Preconditions.checkNotNull(smileMapper, "smileMapper");
Preconditions.checkNotNull(configFactory, "configFactory");
Preconditions.checkState(smileMapper.getJsonFactory() instanceof SmileFactory, "smileMapper should use smile.");
this.nodeType = nodeType;
}
public T setDruidServerMetadata(DruidServerMetadata druidServerMetadata)
{
checkFieldNotSetAndSet("druidServerMetadata", druidServerMetadata);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setCuratorFramework(CuratorFramework curator)
{
checkFieldNotSetAndSet("curator", curator);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setAnnouncer(DataSegmentAnnouncer announcer)
{
checkFieldNotSetAndSet("announcer", announcer);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setEmitter(ServiceEmitter emitter)
{
checkFieldNotSetAndSet("emitter", emitter);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setMonitors(List<Monitor> monitors)
{
checkFieldNotSetAndSet("monitors", monitors);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setServer(Server server)
{
checkFieldNotSetAndSet("server", server);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setZkPaths(ZkPathsConfig zkPaths)
{
checkFieldNotSetAndSet("zkPaths", zkPaths);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setScheduledExecutorFactory(ScheduledExecutorFactory factory)
{
checkFieldNotSetAndSet("scheduledExecutorFactory", factory);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setRequestLogger(RequestLogger requestLogger)
{
checkFieldNotSetAndSet("requestLogger", requestLogger);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setInventoryView(InventoryView inventoryView)
{
checkFieldNotSetAndSet("inventoryView", inventoryView);
return (T) this;
}
@SuppressWarnings("unchecked")
public T setServerView(ServerView serverView)
{
checkFieldNotSetAndSet("serverView", serverView);
return (T) this;
}
@SuppressWarnings("unchecked")
public T registerJacksonSubtype(Class<?>... clazzes)
{
jsonMapper.registerSubtypes(clazzes);
smileMapper.registerSubtypes(clazzes);
return (T) this;
}
@SuppressWarnings("unchecked")
public T registerJacksonSubtype(NamedType... namedTypes)
{
jsonMapper.registerSubtypes(namedTypes);
smileMapper.registerSubtypes(namedTypes);
return (T) this;
}
public Lifecycle getLifecycle()
{
return lifecycle;
}
public ObjectMapper getJsonMapper()
{
return jsonMapper;
}
public ObjectMapper getSmileMapper()
{
return smileMapper;
}
public Properties getProps()
{
return props;
}
public ConfigurationObjectFactory getConfigFactory()
{
return configFactory;
}
public DruidServerMetadata getDruidServerMetadata()
{
initializeDruidServerMetadata();
return druidServerMetadata;
}
public CuratorFramework getCuratorFramework()
{
initializeCuratorFramework();
return curator;
}
public DataSegmentAnnouncer getAnnouncer()
{
initializeAnnouncer();
return announcer;
}
public ServiceEmitter getEmitter()
{
initializeEmitter();
return emitter;
}
public List<Monitor> getMonitors()
{
initializeMonitors();
return monitors;
}
public Server getServer()
{
initializeServer();
return server;
}
public ZkPathsConfig getZkPaths()
{
initializeZkPaths();
return zkPaths;
}
public ScheduledExecutorFactory getScheduledExecutorFactory()
{
initializeScheduledExecutorFactory();
return scheduledExecutorFactory;
}
public RequestLogger getRequestLogger()
{
initializeRequestLogger();
return requestLogger;
}
public ServerView getServerView()
{
initializeServerView();
return serverView;
}
public InventoryView getInventoryView()
{
initializeInventoryView();
return inventoryView;
}
private void initializeDruidServerMetadata()
{
if (druidServerMetadata == null) {
final DruidServerConfig serverConfig = getConfigFactory().build(DruidServerConfig.class);
setDruidServerMetadata(
new DruidServerMetadata(
serverConfig.getServerName(),
serverConfig.getHost(),
serverConfig.getMaxSize(),
nodeType,
serverConfig.getTier()
)
);
}
}
private void initializeServerView()
{
if (serverView == null) {
initializeServerInventoryView();
serverView = serverInventoryView;
}
}
private void initializeInventoryView()
{
if (inventoryView == null) {
initializeServerInventoryView();
inventoryView = serverInventoryView;
}
}
private void initializeServerInventoryView()
{
if (serverInventoryView == null) {
final ExecutorService exec = Executors.newFixedThreadPool(
1, new ThreadFactoryBuilder().setDaemon(true).setNameFormat("ServerInventoryView-%s").build()
);
final ServerInventoryViewConfig serverInventoryViewConfig = getConfigFactory().build(ServerInventoryViewConfig.class);
final String announcerType = serverInventoryViewConfig.getAnnouncerType();
if ("legacy".equalsIgnoreCase(announcerType)) {
serverInventoryView = new SingleServerInventoryView(
serverInventoryViewConfig,
getZkPaths(),
getCuratorFramework(),
exec,
getJsonMapper()
);
} else if ("batch".equalsIgnoreCase(announcerType)) {
serverInventoryView = new BatchServerInventoryView(
serverInventoryViewConfig,
getZkPaths(),
getCuratorFramework(),
exec,
getJsonMapper()
);
} else {
throw new IAE("Unknown type %s", announcerType);
}
lifecycle.addManagedInstance(serverInventoryView);
}
}
private void initializeRequestLogger()
{
if (requestLogger == null) {
try {
final String loggingType = props.getProperty("druid.request.logging.type");
if ("emitter".equals(loggingType)) {
setRequestLogger(
Initialization.makeEmittingRequestLogger(
getProps(),
getEmitter()
)
);
} else if ("file".equalsIgnoreCase(loggingType)) {
setRequestLogger(
Initialization.makeFileRequestLogger(
getJsonMapper(),
getScheduledExecutorFactory(),
getProps()
)
);
} else {
setRequestLogger(new NoopRequestLogger());
}
}
catch (IOException e) {
throw Throwables.propagate(e);
}
lifecycle.addManagedInstance(requestLogger);
}
}
private void initializeZkPaths()
{
if (zkPaths == null) {
setZkPaths(getConfigFactory().build(ZkPathsConfig.class));
}
}
private void initializeScheduledExecutorFactory()
{
if (scheduledExecutorFactory == null) {
setScheduledExecutorFactory(ScheduledExecutors.createFactory(getLifecycle()));
}
}
private void initializeCuratorFramework()
{
if (curator == null) {
try {
setCuratorFramework(Initialization.makeCuratorFramework(configFactory.build(CuratorConfig.class), lifecycle));
}
catch (IOException e) {
throw Throwables.propagate(e);
}
}
}
private void initializeAnnouncer()
{
if (announcer == null) {
final Announcer announcer = new Announcer(getCuratorFramework(), Execs.singleThreaded("Announcer-%s"));
lifecycle.addManagedInstance(announcer);
final ZkDataSegmentAnnouncerConfig config = getConfigFactory().build(ZkDataSegmentAnnouncerConfig.class);
final String announcerType = config.getAnnouncerType();
final DataSegmentAnnouncer dataSegmentAnnouncer;
if ("batch".equalsIgnoreCase(announcerType)) {
dataSegmentAnnouncer = new BatchDataSegmentAnnouncer(
getDruidServerMetadata(),
config,
announcer,
getJsonMapper()
);
} else if ("legacy".equalsIgnoreCase(announcerType)) {
dataSegmentAnnouncer = new MultipleDataSegmentAnnouncerDataSegmentAnnouncer(
Arrays.<AbstractDataSegmentAnnouncer>asList(
new BatchDataSegmentAnnouncer(
getDruidServerMetadata(),
config,
announcer,
getJsonMapper()
),
new SingleDataSegmentAnnouncer(
getDruidServerMetadata(),
getZkPaths(),
announcer,
getJsonMapper()
)
)
);
} else {
throw new ISE("Unknown announcer type [%s]", announcerType);
}
setAnnouncer(dataSegmentAnnouncer);
lifecycle.addManagedInstance(getAnnouncer(), Lifecycle.Stage.LAST);
}
}
private void initializeServer()
{
if (server == null) {
setServer(Initialization.makeJettyServer(configFactory.build(ServerConfig.class)));
lifecycle.addHandler(
new Lifecycle.Handler()
{
@Override
public void start() throws Exception
{
log.info("Starting Jetty");
server.start();
}
@Override
public void stop()
{
log.info("Stopping Jetty");
try {
server.stop();
}
catch (Exception e) {
log.error(e, "Exception thrown while stopping Jetty");
}
}
}
);
}
}
private void initializeMonitors()
{
if (monitors == null) {
List<Monitor> theMonitors = Lists.newArrayList();
theMonitors.add(new JvmMonitor());
if (Boolean.parseBoolean(props.getProperty("druid.monitoring.monitorSystem", "false"))) {
theMonitors.add(new SysMonitor());
}
setMonitors(theMonitors);
}
}
private void initializeEmitter()
{
if (emitter == null) {
final HttpClientConfig.Builder configBuilder = HttpClientConfig.builder().withNumConnections(1);
final String emitterTimeoutDuration = props.getProperty("druid.emitter.timeOut");
if (emitterTimeoutDuration != null) {
configBuilder.withReadTimeout(new Duration(emitterTimeoutDuration));
}
final HttpClient httpClient = HttpClientInit.createClient(configBuilder.build(), lifecycle);
setEmitter(
new ServiceEmitter(
PropUtils.getProperty(props, "druid.service"),
PropUtils.getProperty(props, "druid.host"),
Emitters.create(props, httpClient, jsonMapper, lifecycle)
)
);
}
EmittingLogger.registerEmitter(emitter);
}
protected void init() throws Exception
{
doInit();
initialized = true;
}
protected abstract void doInit() throws Exception;
@LifecycleStart
public synchronized void start() throws Exception
{
if (!initialized) {
init();
}
lifecycle.start();
}
@LifecycleStop
public synchronized void stop()
{
lifecycle.stop();
}
protected ScheduledExecutorService startMonitoring(List<Monitor> monitors)
{
final ScheduledExecutorService globalScheduledExec = getScheduledExecutorFactory().create(1, "Global--%d");
final MonitorScheduler monitorScheduler = new MonitorScheduler(
getConfigFactory().build(MonitorSchedulerConfig.class),
globalScheduledExec,
getEmitter(),
monitors
);
getLifecycle().addManagedInstance(monitorScheduler);
return globalScheduledExec;
}
protected void checkFieldNotSetAndSet(String fieldName, Object value)
{
Class<?> theClazz = this.getClass();
while (theClazz != null && theClazz != Object.class) {
try {
final Field field = theClazz.getDeclaredField(fieldName);
field.setAccessible(true);
Preconditions.checkState(field.get(this) == null, "Cannot set %s once it has already been set.", fieldName);
field.set(this, value);
return;
}
catch (NoSuchFieldException e) {
// Perhaps it is inherited?
theClazz = theClazz.getSuperclass();
}
catch (IllegalAccessException e) {
throw Throwables.propagate(e);
}
}
throw new ISE("Unknown field[%s] on class[%s]", fieldName, this.getClass());
}
}

View File

@ -1,406 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.client;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.metamx.common.Granularity;
import com.metamx.druid.jackson.CommaListJoinDeserializer;
import com.metamx.druid.jackson.CommaListJoinSerializer;
import com.metamx.druid.query.segment.SegmentDescriptor;
import com.metamx.druid.shard.NoneShardSpec;
import com.metamx.druid.shard.ShardSpec;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import javax.annotation.Nullable;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
/**
*/
public class DataSegment implements Comparable<DataSegment>
{
public static String delimiter = "_";
private final Integer binaryVersion;
public static String makeDataSegmentIdentifier(
String dataSource,
DateTime start,
DateTime end,
String version,
ShardSpec shardSpec
)
{
StringBuilder sb = new StringBuilder();
sb.append(dataSource).append(delimiter)
.append(start).append(delimiter)
.append(end).append(delimiter)
.append(version);
if (shardSpec.getPartitionNum() != 0) {
sb.append(delimiter).append(shardSpec.getPartitionNum());
}
return sb.toString();
}
private final String dataSource;
private final Interval interval;
private final String version;
private final Map<String, Object> loadSpec;
private final List<String> dimensions;
private final List<String> metrics;
private final ShardSpec shardSpec;
private final long size;
private final String identifier;
@JsonCreator
public DataSegment(
@JsonProperty("dataSource") String dataSource,
@JsonProperty("interval") Interval interval,
@JsonProperty("version") String version,
@JsonProperty("loadSpec") Map<String, Object> loadSpec,
@JsonProperty("dimensions") @JsonDeserialize(using = CommaListJoinDeserializer.class) List<String> dimensions,
@JsonProperty("metrics") @JsonDeserialize(using = CommaListJoinDeserializer.class) List<String> metrics,
@JsonProperty("shardSpec") ShardSpec shardSpec,
@JsonProperty("binaryVersion") Integer binaryVersion,
@JsonProperty("size") long size
)
{
final Predicate<String> nonEmpty = new Predicate<String>()
{
@Override
public boolean apply(@Nullable String input)
{
return input != null && !input.isEmpty();
}
};
this.dataSource = dataSource.toLowerCase();
this.interval = interval;
this.loadSpec = loadSpec;
this.version = version;
this.dimensions = dimensions == null
? ImmutableList.<String>of()
: ImmutableList.copyOf(Iterables.filter(dimensions, nonEmpty));
this.metrics = metrics == null
? ImmutableList.<String>of()
: ImmutableList.copyOf(Iterables.filter(metrics, nonEmpty));
this.shardSpec = (shardSpec == null) ? new NoneShardSpec() : shardSpec;
this.binaryVersion = binaryVersion;
this.size = size;
this.identifier = makeDataSegmentIdentifier(
this.dataSource,
this.interval.getStart(),
this.interval.getEnd(),
this.version,
this.shardSpec
);
}
/**
* Get dataSource
*
* @return the dataSource
*/
@JsonProperty
public String getDataSource()
{
return dataSource;
}
@JsonProperty
public Interval getInterval()
{
return interval;
}
@JsonProperty
public Map<String, Object> getLoadSpec()
{
return loadSpec;
}
@JsonProperty
public String getVersion()
{
return version;
}
@JsonProperty
@JsonSerialize(using = CommaListJoinSerializer.class)
public List<String> getDimensions()
{
return dimensions;
}
@JsonProperty
@JsonSerialize(using = CommaListJoinSerializer.class)
public List<String> getMetrics()
{
return metrics;
}
@JsonProperty
public ShardSpec getShardSpec()
{
return shardSpec;
}
@JsonProperty
public Integer getBinaryVersion()
{
return binaryVersion;
}
@JsonProperty
public long getSize()
{
return size;
}
@JsonProperty
public String getIdentifier()
{
return identifier;
}
public SegmentDescriptor toDescriptor()
{
return new SegmentDescriptor(interval, version, shardSpec.getPartitionNum());
}
public DataSegment withLoadSpec(Map<String, Object> loadSpec)
{
return builder(this).loadSpec(loadSpec).build();
}
public DataSegment withDimensions(List<String> dimensions)
{
return builder(this).dimensions(dimensions).build();
}
public DataSegment withSize(long size)
{
return builder(this).size(size).build();
}
public DataSegment withVersion(String version)
{
return builder(this).version(version).build();
}
public DataSegment withBinaryVersion(int binaryVersion)
{
return builder(this).binaryVersion(binaryVersion).build();
}
@Override
public int compareTo(DataSegment dataSegment)
{
return getIdentifier().compareTo(dataSegment.getIdentifier());
}
@Override
public boolean equals(Object o)
{
if (o instanceof DataSegment) {
return getIdentifier().equals(((DataSegment) o).getIdentifier());
}
return false;
}
@Override
public int hashCode()
{
return getIdentifier().hashCode();
}
@Override
public String toString()
{
return "DataSegment{" +
"size=" + size +
", shardSpec=" + shardSpec +
", metrics=" + metrics +
", dimensions=" + dimensions +
", version='" + version + '\'' +
", loadSpec=" + loadSpec +
", interval=" + interval +
", dataSource='" + dataSource + '\'' +
", binaryVersion='" + binaryVersion + '\'' +
'}';
}
public static Comparator<DataSegment> bucketMonthComparator()
{
return new Comparator<DataSegment>()
{
@Override
public int compare(DataSegment lhs, DataSegment rhs)
{
int retVal;
DateTime lhsMonth = Granularity.MONTH.truncate(lhs.getInterval().getStart());
DateTime rhsMonth = Granularity.MONTH.truncate(rhs.getInterval().getStart());
retVal = lhsMonth.compareTo(rhsMonth);
if (retVal != 0) {
return retVal;
}
return lhs.compareTo(rhs);
}
};
}
public static Builder builder()
{
return new Builder();
}
public static Builder builder(DataSegment segment)
{
return new Builder(segment);
}
public static class Builder
{
private String dataSource;
private Interval interval;
private String version;
private Map<String, Object> loadSpec;
private List<String> dimensions;
private List<String> metrics;
private ShardSpec shardSpec;
private Integer binaryVersion;
private long size;
public Builder()
{
this.loadSpec = ImmutableMap.of();
this.dimensions = ImmutableList.of();
this.metrics = ImmutableList.of();
this.shardSpec = new NoneShardSpec();
this.size = -1;
}
public Builder(DataSegment segment)
{
this.dataSource = segment.getDataSource();
this.interval = segment.getInterval();
this.version = segment.getVersion();
this.loadSpec = segment.getLoadSpec();
this.dimensions = segment.getDimensions();
this.metrics = segment.getMetrics();
this.shardSpec = segment.getShardSpec();
this.binaryVersion = segment.getBinaryVersion();
this.size = segment.getSize();
}
public Builder dataSource(String dataSource)
{
this.dataSource = dataSource;
return this;
}
public Builder interval(Interval interval)
{
this.interval = interval;
return this;
}
public Builder version(String version)
{
this.version = version;
return this;
}
public Builder loadSpec(Map<String, Object> loadSpec)
{
this.loadSpec = loadSpec;
return this;
}
public Builder dimensions(List<String> dimensions)
{
this.dimensions = dimensions;
return this;
}
public Builder metrics(List<String> metrics)
{
this.metrics = metrics;
return this;
}
public Builder shardSpec(ShardSpec shardSpec)
{
this.shardSpec = shardSpec;
return this;
}
public Builder binaryVersion(Integer binaryVersion)
{
this.binaryVersion = binaryVersion;
return this;
}
public Builder size(long size)
{
this.size = size;
return this;
}
public DataSegment build()
{
// Check stuff that goes into the identifier, at least.
Preconditions.checkNotNull(dataSource, "dataSource");
Preconditions.checkNotNull(interval, "interval");
Preconditions.checkNotNull(version, "version");
Preconditions.checkNotNull(shardSpec, "shardSpec");
return new DataSegment(
dataSource,
interval,
version,
loadSpec,
dimensions,
metrics,
shardSpec,
binaryVersion,
size
);
}
}
}

View File

@ -1,9 +0,0 @@
package com.metamx.druid.client;
/**
*/
public interface InventoryView
{
public DruidServer getInventoryValue(String string);
public Iterable<DruidServer> getInventory();
}

View File

@ -1,36 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.client;
import org.skife.config.Config;
import org.skife.config.Default;
/**
*/
public abstract class ServerInventoryViewConfig
{
@Config("druid.master.removedSegmentLifetime")
@Default("1")
public abstract int getRemovedSegmentLifetime();
@Config("druid.announcer.type")
@Default("legacy")
public abstract String getAnnouncerType();
}

View File

@ -1,11 +0,0 @@
package com.metamx.druid.client.cache;
import org.skife.config.Config;
import org.skife.config.Default;
public abstract class CacheConfig
{
@Config("druid.bard.cache.type")
@Default("local")
public abstract String getType();
}

View File

@ -1,26 +0,0 @@
package com.metamx.druid.client.cache;
import org.skife.config.Config;
import org.skife.config.Default;
public abstract class MemcachedCacheConfig
{
@Config("${prefix}.expiration")
@Default("2592000")
public abstract int getExpiration();
@Config("${prefix}.timeout")
@Default("500")
public abstract int getTimeout();
@Config("${prefix}.hosts")
public abstract String getHosts();
@Config("${prefix}.maxObjectSize")
@Default("52428800")
public abstract int getMaxObjectSize();
@Config("${prefix}.memcachedPrefix")
@Default("druid")
public abstract String getMemcachedPrefix();
}

View File

@ -1,27 +0,0 @@
package com.metamx.druid.curator.discovery;
import com.google.common.base.Throwables;
import org.apache.curator.x.discovery.ServiceInstance;
public class AddressPortServiceInstanceFactory implements ServiceInstanceFactory<Void>
{
private final String address;
private final int port;
public AddressPortServiceInstanceFactory(String address, int port)
{
this.address = address;
this.port = port;
}
@Override
public ServiceInstance<Void> create(String service)
{
try {
return ServiceInstance.<Void>builder().name(service).address(address).port(port).build();
}
catch (Exception e) {
throw Throwables.propagate(e);
}
}
}

View File

@ -1,81 +0,0 @@
package com.metamx.druid.curator.discovery;
import com.google.common.collect.Maps;
import com.metamx.common.logger.Logger;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceInstance;
import java.util.Map;
/**
* Uses the Curator Service Discovery recipe to announce services.
*/
public class CuratorServiceAnnouncer<T> implements ServiceAnnouncer
{
private static final Logger log = new Logger(CuratorServiceAnnouncer.class);
private final ServiceDiscovery<T> discovery;
private final ServiceInstanceFactory<T> instanceFactory;
private final Map<String, ServiceInstance<T>> instanceMap = Maps.newHashMap();
private final Object monitor = new Object();
public CuratorServiceAnnouncer(
ServiceDiscovery<T> discovery,
ServiceInstanceFactory<T> instanceFactory
)
{
this.discovery = discovery;
this.instanceFactory = instanceFactory;
}
@Override
public void announce(String service) throws Exception
{
final ServiceInstance<T> instance;
synchronized (monitor) {
if (instanceMap.containsKey(service)) {
log.warn("Ignoring request to announce service[%s]", service);
return;
} else {
instance = instanceFactory.create(service);
instanceMap.put(service, instance);
}
}
try {
log.info("Announcing service[%s]", service);
discovery.registerService(instance);
} catch (Exception e) {
log.warn("Failed to announce service[%s]", service);
synchronized (monitor) {
instanceMap.remove(service);
}
}
}
@Override
public void unannounce(String service) throws Exception
{
final ServiceInstance<T> instance;
synchronized (monitor) {
instance = instanceMap.get(service);
if (instance == null) {
log.warn("Ignoring request to unannounce service[%s]", service);
return;
}
}
log.info("Unannouncing service[%s]", service);
try {
discovery.unregisterService(instance);
} catch (Exception e) {
log.warn(e, "Failed to unannounce service[%s]", service);
} finally {
synchronized (monitor) {
instanceMap.remove(service);
}
}
}
}

View File

@ -1,19 +0,0 @@
package com.metamx.druid.curator.discovery;
/**
* Does nothing.
*/
public class NoopServiceAnnouncer implements ServiceAnnouncer
{
@Override
public void unannounce(String service)
{
}
@Override
public void announce(String service)
{
}
}

View File

@ -1,11 +0,0 @@
package com.metamx.druid.curator.discovery;
/**
* Announces our ability to serve a particular function. Multiple users may announce the same service, in which
* case they are treated as interchangeable instances of that service.
*/
public interface ServiceAnnouncer
{
public void announce(String service) throws Exception;
public void unannounce(String service) throws Exception;
}

View File

@ -1,8 +0,0 @@
package com.metamx.druid.curator.discovery;
import org.apache.curator.x.discovery.ServiceInstance;
public interface ServiceInstanceFactory<T>
{
public ServiceInstance<T> create(String service);
}

View File

@ -1,352 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.http;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.servlet.GuiceFilter;
import com.metamx.common.ISE;
import com.metamx.common.config.Config;
import com.metamx.common.lifecycle.Lifecycle;
import com.metamx.common.logger.Logger;
import com.metamx.druid.QueryableNode;
import com.metamx.druid.client.BrokerServerView;
import com.metamx.druid.client.CachingClusteredClient;
import com.metamx.druid.client.cache.Cache;
import com.metamx.druid.client.cache.CacheConfig;
import com.metamx.druid.client.cache.CacheMonitor;
import com.metamx.druid.client.cache.MapCache;
import com.metamx.druid.client.cache.MapCacheConfig;
import com.metamx.druid.client.cache.MemcachedCache;
import com.metamx.druid.client.cache.MemcachedCacheConfig;
import com.metamx.druid.curator.discovery.ServiceAnnouncer;
import com.metamx.druid.curator.discovery.ServiceInstanceFactory;
import com.metamx.druid.initialization.Initialization;
import com.metamx.druid.initialization.ServiceDiscoveryConfig;
import com.metamx.druid.jackson.DefaultObjectMapper;
import com.metamx.druid.query.QueryToolChestWarehouse;
import com.metamx.druid.query.ReflectionQueryToolChestWarehouse;
import com.metamx.druid.utils.PropUtils;
import com.metamx.http.client.HttpClient;
import com.metamx.http.client.HttpClientConfig;
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.skife.config.ConfigurationObjectFactory;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*/
public class BrokerNode extends QueryableNode<BrokerNode>
{
private static final Logger log = new Logger(BrokerNode.class);
public static final String CACHE_TYPE_LOCAL = "local";
public static final String CACHE_TYPE_MEMCACHED = "memcached";
public static final String CACHE_PROPERTY_PREFIX = "druid.bard.cache";
private final List<Module> extraModules = Lists.newArrayList();
private final List<String> pathsForGuiceFilter = Lists.newArrayList();
private QueryToolChestWarehouse warehouse = null;
private HttpClient brokerHttpClient = null;
private Cache cache = null;
private boolean useDiscovery = true;
public static Builder builder()
{
return new Builder();
}
public BrokerNode(
Properties props,
Lifecycle lifecycle,
ObjectMapper jsonMapper,
ObjectMapper smileMapper,
ConfigurationObjectFactory configFactory
)
{
super("broker", log, props, lifecycle, jsonMapper, smileMapper, configFactory);
}
public QueryToolChestWarehouse getWarehouse()
{
initializeWarehouse();
return warehouse;
}
public BrokerNode setWarehouse(QueryToolChestWarehouse warehouse)
{
checkFieldNotSetAndSet("warehouse", warehouse);
return this;
}
public HttpClient getBrokerHttpClient()
{
initializeBrokerHttpClient();
return brokerHttpClient;
}
public BrokerNode setBrokerHttpClient(HttpClient brokerHttpClient)
{
checkFieldNotSetAndSet("brokerHttpClient", brokerHttpClient);
return this;
}
public Cache getCache()
{
initializeCacheBroker();
return cache;
}
public BrokerNode setCache(Cache cache)
{
checkFieldNotSetAndSet("cache", cache);
return this;
}
public BrokerNode useDiscovery(boolean useDiscovery)
{
this.useDiscovery = useDiscovery;
return this;
}
/**
* This method allows you to specify more Guice modules to use primarily for injected extra Jersey resources.
* I'd like to remove the Guice dependency for this, but I don't know how to set up Jersey without Guice...
*
* This is deprecated because at some point in the future, we will eliminate the Guice dependency and anything
* that uses this will break. Use at your own risk.
*
* @param module the module to register with Guice
*
* @return this
*/
@Deprecated
public BrokerNode addModule(Module module)
{
extraModules.add(module);
return this;
}
/**
* This method is used to specify extra paths that the GuiceFilter should pay attention to.
*
* This is deprecated for the same reason that addModule is deprecated.
*
* @param path the path that the GuiceFilter should pay attention to.
*
* @return this
*/
@Deprecated
public BrokerNode addPathForGuiceFilter(String path)
{
pathsForGuiceFilter.add(path);
return this;
}
@Override
protected void doInit() throws Exception
{
initializeWarehouse();
initializeBrokerHttpClient();
initializeCacheBroker();
initializeDiscovery();
final Lifecycle lifecycle = getLifecycle();
final List<Monitor> monitors = getMonitors();
monitors.add(new CacheMonitor(cache));
startMonitoring(monitors);
final ExecutorService viewExec = Executors.newFixedThreadPool(
1, new ThreadFactoryBuilder().setDaemon(true).setNameFormat("BrokerServerView-%s").build()
);
final BrokerServerView view = new BrokerServerView(
warehouse, getSmileMapper(), brokerHttpClient, getServerView(), viewExec
);
final CachingClusteredClient baseClient = new CachingClusteredClient(warehouse, view, cache, getSmileMapper());
lifecycle.addManagedInstance(baseClient);
final ClientQuerySegmentWalker texasRanger = new ClientQuerySegmentWalker(warehouse, getEmitter(), baseClient);
List<Module> theModules = Lists.newArrayList();
theModules.add(new ClientServletModule(texasRanger, getInventoryView(), getJsonMapper()));
theModules.addAll(extraModules);
final Injector injector = Guice.createInjector(theModules);
final Context root = new Context(getServer(), "/", Context.SESSIONS);
root.addServlet(new ServletHolder(new StatusServlet()), "/status");
root.addServlet(
new ServletHolder(new QueryServlet(getJsonMapper(), getSmileMapper(), texasRanger, getEmitter(), getRequestLogger())),
"/druid/v2/*"
);
root.addFilter(GzipFilter.class, "/*", 0);
root.addEventListener(new GuiceServletConfig(injector));
root.addFilter(GuiceFilter.class, "/druid/v2/datasources/*", 0);
for (String path : pathsForGuiceFilter) {
root.addFilter(GuiceFilter.class, path, 0);
}
}
private void initializeDiscovery() throws Exception
{
if (useDiscovery) {
final Lifecycle lifecycle = getLifecycle();
final ServiceDiscoveryConfig serviceDiscoveryConfig = getConfigFactory().build(ServiceDiscoveryConfig.class);
final CuratorFramework curatorFramework = Initialization.makeCuratorFramework(
serviceDiscoveryConfig, lifecycle
);
final ServiceDiscovery serviceDiscovery = Initialization.makeServiceDiscoveryClient(
curatorFramework, serviceDiscoveryConfig, lifecycle
);
final ServiceAnnouncer serviceAnnouncer = Initialization.makeServiceAnnouncer(
serviceDiscoveryConfig, serviceDiscovery
);
Initialization.announceDefaultService(serviceDiscoveryConfig, serviceAnnouncer, lifecycle);
}
}
private void initializeCacheBroker()
{
if (cache == null) {
String cacheType = getConfigFactory()
.build(CacheConfig.class)
.getType();
if (cacheType.equals(CACHE_TYPE_LOCAL)) {
setCache(
MapCache.create(
getConfigFactory().buildWithReplacements(
MapCacheConfig.class,
ImmutableMap.of("prefix", CACHE_PROPERTY_PREFIX)
)
)
);
} else if (cacheType.equals(CACHE_TYPE_MEMCACHED)) {
setCache(
MemcachedCache.create(
getConfigFactory().buildWithReplacements(
MemcachedCacheConfig.class,
ImmutableMap.of("prefix", CACHE_PROPERTY_PREFIX)
)
)
);
} else {
throw new ISE("Unknown cache type [%s]", cacheType);
}
}
}
private void initializeBrokerHttpClient()
{
if (brokerHttpClient == null) {
setBrokerHttpClient(
HttpClientInit.createClient(
HttpClientConfig
.builder()
.withNumConnections(PropUtils.getPropertyAsInt(getProps(), "druid.client.http.connections"))
.build(),
getLifecycle()
)
);
}
}
private void initializeWarehouse()
{
if (warehouse == null) {
setWarehouse(new ReflectionQueryToolChestWarehouse());
}
}
public static class Builder
{
private ObjectMapper jsonMapper = null;
private ObjectMapper smileMapper = null;
private Lifecycle lifecycle = null;
private Properties props = null;
private ConfigurationObjectFactory configFactory = null;
public Builder withMappers(ObjectMapper jsonMapper, ObjectMapper smileMapper)
{
this.jsonMapper = jsonMapper;
this.smileMapper = smileMapper;
return this;
}
public Builder withProps(Properties props)
{
this.props = props;
return this;
}
public Builder withConfigFactory(ConfigurationObjectFactory configFactory)
{
this.configFactory = configFactory;
return this;
}
public BrokerNode build()
{
if (jsonMapper == null && smileMapper == null) {
jsonMapper = new DefaultObjectMapper();
smileMapper = new DefaultObjectMapper(new SmileFactory());
smileMapper.getJsonFactory().setCodec(smileMapper);
}
else if (jsonMapper == null || smileMapper == null) {
throw new ISE("Only jsonMapper[%s] or smileMapper[%s] was set, must set neither or both.", jsonMapper, smileMapper);
}
if (lifecycle == null) {
lifecycle = new Lifecycle();
}
if (props == null) {
props = Initialization.loadProperties();
}
if (configFactory == null) {
configFactory = Config.createFactory(props);
}
return new BrokerNode(props, lifecycle, jsonMapper, smileMapper, configFactory);
}
}
}

View File

@ -1,41 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.http;
/**
*/
@Deprecated
public class ClientMain
{
public static void main(String[] args) throws Exception
{
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("!@(*&$#!(*@(@*&$! You are running with ClientMain!!!! PLZ Stop. Use BrokerMain instead.");
System.out.println("K thx bye.");
BrokerMain.main(args);
}
}

View File

@ -1,70 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.http;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import com.google.inject.Provides;
import com.metamx.druid.client.InventoryView;
import com.metamx.druid.query.segment.QuerySegmentWalker;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import javax.inject.Singleton;
/**
*/
public class ClientServletModule extends JerseyServletModule
{
private final QuerySegmentWalker texasRanger;
private final InventoryView serverInventoryView;
private final ObjectMapper jsonMapper;
public ClientServletModule(
QuerySegmentWalker texasRanger,
InventoryView serverInventoryView,
ObjectMapper jsonMapper
)
{
this.texasRanger = texasRanger;
this.serverInventoryView = serverInventoryView;
this.jsonMapper = jsonMapper;
}
@Override
protected void configureServlets()
{
bind(ClientInfoResource.class);
bind(QuerySegmentWalker.class).toInstance(texasRanger);
bind(InventoryView.class).toInstance(serverInventoryView);
serve("/*").with(GuiceContainer.class);
}
@Provides
@Singleton
public JacksonJsonProvider getJacksonJsonProvider()
{
final JacksonJsonProvider provider = new JacksonJsonProvider();
provider.setMapper(jsonMapper);
return provider;
}
}

View File

@ -1,57 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.http;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
/**
*/
public class StatusServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
ByteArrayOutputStream retVal = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(new OutputStreamWriter(retVal));
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory();
long totalMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();
out.printf("Max Memory:\t%,18d\t%1$d%n", maxMemory);
out.printf("Total Memory:\t%,18d\t%1$d%n", totalMemory);
out.printf("Free Memory:\t%,18d\t%1$d%n", freeMemory);
out.printf("Used Memory:\t%,18d\t%1$d%n", totalMemory - freeMemory);
out.flush();
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("text/plain");
resp.getOutputStream().write(retVal.toByteArray());
}
}

View File

@ -1,372 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.initialization;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import com.google.common.io.Closeables;
import com.metamx.common.concurrent.ScheduledExecutorFactory;
import com.metamx.common.config.Config;
import com.metamx.common.lifecycle.Lifecycle;
import com.metamx.common.logger.Logger;
import com.metamx.druid.curator.PotentiallyGzippedCompressionProvider;
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.http.EmittingRequestLogger;
import com.metamx.druid.http.FileRequestLogger;
import com.metamx.druid.http.RequestLogger;
import com.metamx.druid.utils.PropUtils;
import com.metamx.emitter.core.Emitter;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.BoundedExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
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.skife.config.ConfigurationObjectFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
/**
*/
public class Initialization
{
private static final Logger log = new Logger(Initialization.class);
private static final String PROPERTIES_FILE = "runtime.properties";
private static final Properties zkProps = new Properties();
private static final Properties fileProps = new Properties(zkProps);
private static Properties props = null;
/**
* Load properties.
* Properties are layered:
* <p/>
* # stored in zookeeper
* # runtime.properties file,
* # cmdLine -D
* <p/>
* command line overrides runtime.properties which overrides zookeeper
* <p/>
* Idempotent. Thread-safe. Properties are only loaded once.
* If property druid.zk.service.host is not set then do not load properties from zookeeper.
*
* @return Properties ready to use.
*/
public synchronized static Properties loadProperties()
{
if (props != null) {
return props;
}
// Note that zookeeper coordinates must be either in cmdLine or in runtime.properties
Properties sp = System.getProperties();
Properties tmp_props = new Properties(fileProps); // the head of the 3 level Properties chain
tmp_props.putAll(sp);
final InputStream stream = ClassLoader.getSystemResourceAsStream(PROPERTIES_FILE);
if (stream == null) {
log.info("%s not found on classpath, relying only on system properties and zookeeper.", PROPERTIES_FILE);
} else {
log.info("Loading properties from %s", PROPERTIES_FILE);
try {
try {
fileProps.load(stream);
}
catch (IOException e) {
throw Throwables.propagate(e);
}
}
finally {
Closeables.closeQuietly(stream);
}
}
// log properties from file; stringPropertyNames() would normally cascade down into the sub Properties objects, but
// zkProps (the parent level) is empty at this point so it will only log properties from runtime.properties
for (String prop : fileProps.stringPropertyNames()) {
log.info("Loaded(runtime.properties) Property[%s] as [%s]", prop, fileProps.getProperty(prop));
}
final String zkHostsProperty = "druid.zk.service.host";
if (tmp_props.getProperty(zkHostsProperty) != null) {
final ConfigurationObjectFactory factory = Config.createFactory(tmp_props);
ZkPathsConfig config;
try {
config = factory.build(ZkPathsConfig.class);
}
catch (IllegalArgumentException e) {
log.warn(e, "Unable to build ZkPathsConfig. Cannot load properties from ZK.");
config = null;
}
if (config != null) {
Lifecycle lifecycle = new Lifecycle();
try {
CuratorFramework curator = makeCuratorFramework(factory.build(CuratorConfig.class), lifecycle);
lifecycle.start();
final Stat stat = curator.checkExists().forPath(config.getPropertiesPath());
if (stat != null) {
final byte[] data = curator.getData().forPath(config.getPropertiesPath());
zkProps.load(new InputStreamReader(new ByteArrayInputStream(data), Charsets.UTF_8));
}
// log properties from zk
for (String prop : zkProps.stringPropertyNames()) {
log.info("Loaded(zk) Property[%s] as [%s]", prop, zkProps.getProperty(prop));
}
}
catch (Exception e) {
throw Throwables.propagate(e);
}
finally {
lifecycle.stop();
}
}
} else {
log.warn("property[%s] not set, skipping ZK-specified properties.", zkHostsProperty);
}
props = tmp_props;
return props;
}
public static Server makeJettyServer(ServerConfig config)
{
final QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setMinThreads(config.getNumThreads());
threadPool.setMaxThreads(config.getNumThreads());
final Server server = new Server();
server.setThreadPool(threadPool);
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(config.getPort());
connector.setMaxIdleTime(config.getMaxIdleTimeMillis());
connector.setStatsOn(true);
server.setConnectors(new Connector[]{connector});
return server;
}
public static CuratorFramework makeCuratorFramework(
CuratorConfig curatorConfig,
Lifecycle lifecycle
) throws IOException
{
final CuratorFramework framework =
CuratorFrameworkFactory.builder()
.connectString(curatorConfig.getZkHosts())
.sessionTimeoutMs(curatorConfig.getZkSessionTimeoutMs())
.retryPolicy(new BoundedExponentialBackoffRetry(1000, 45000, 30))
.compressionProvider(new PotentiallyGzippedCompressionProvider(curatorConfig.enableCompression()))
.build();
lifecycle.addHandler(
new Lifecycle.Handler()
{
@Override
public void start() throws Exception
{
framework.start();
}
@Override
public void stop()
{
framework.close();
}
}
);
return framework;
}
public static ServiceDiscovery makeServiceDiscoveryClient(
CuratorFramework discoveryClient,
ServiceDiscoveryConfig config,
Lifecycle lifecycle
)
throws Exception
{
final ServiceDiscovery serviceDiscovery =
ServiceDiscoveryBuilder.builder(Void.class)
.basePath(config.getDiscoveryPath())
.client(discoveryClient)
.build();
lifecycle.addHandler(
new Lifecycle.Handler()
{
@Override
public void start() throws Exception
{
serviceDiscovery.start();
}
@Override
public void stop()
{
try {
serviceDiscovery.close();
}
catch (Exception e) {
throw Throwables.propagate(e);
}
}
}
);
return serviceDiscovery;
}
public static ServiceAnnouncer makeServiceAnnouncer(
ServiceDiscoveryConfig config,
ServiceDiscovery serviceDiscovery
)
{
final ServiceInstanceFactory serviceInstanceFactory = makeServiceInstanceFactory(config);
return new CuratorServiceAnnouncer(serviceDiscovery, serviceInstanceFactory);
}
public static void announceDefaultService(
final ServiceDiscoveryConfig config,
final ServiceAnnouncer serviceAnnouncer,
final Lifecycle lifecycle
) throws Exception
{
final String service = config.getServiceName().replace('/', ':');
lifecycle.addHandler(
new Lifecycle.Handler()
{
@Override
public void start() throws Exception
{
serviceAnnouncer.announce(service);
}
@Override
public void stop()
{
try {
serviceAnnouncer.unannounce(service);
}
catch (Exception e) {
log.warn(e, "Failed to unannouce default service[%s]", service);
}
}
}
);
}
public static ServiceProvider makeServiceProvider(
String serviceName,
ServiceDiscovery serviceDiscovery,
Lifecycle lifecycle
)
{
final ServiceProvider serviceProvider = serviceDiscovery.serviceProviderBuilder()
.serviceName(serviceName)
.build();
lifecycle.addHandler(
new Lifecycle.Handler()
{
@Override
public void start() throws Exception
{
serviceProvider.start();
}
@Override
public void stop()
{
try {
serviceProvider.close();
}
catch (Exception e) {
throw Throwables.propagate(e);
}
}
}
);
return serviceProvider;
}
public static RequestLogger makeFileRequestLogger(
ObjectMapper objectMapper,
ScheduledExecutorFactory factory,
Properties props
) throws IOException
{
return new FileRequestLogger(
objectMapper,
factory.create(1, "RequestLogger-%s"),
new File(PropUtils.getProperty(props, "druid.request.logging.dir"))
);
}
public static RequestLogger makeEmittingRequestLogger(Properties props, Emitter emitter)
{
return new EmittingRequestLogger(
PropUtils.getProperty(props, "druid.service"),
PropUtils.getProperty(props, "druid.host"),
emitter,
PropUtils.getProperty(props, "druid.request.logging.feed")
);
}
public static ServiceInstanceFactory<Void> makeServiceInstanceFactory(ServiceDiscoveryConfig config)
{
final String host = config.getHost();
final String address;
final int colon = host.indexOf(':');
if (colon < 0) {
address = host;
} else {
address = host.substring(0, colon);
}
return new AddressPortServiceInstanceFactory(address, config.getPort());
}
}

View File

@ -1,21 +0,0 @@
package com.metamx.druid.initialization;
import org.skife.config.Config;
import org.skife.config.Default;
/**
*/
public abstract class ZkDataSegmentAnnouncerConfig extends ZkPathsConfig
{
@Config("druid.zk.segmentsPerNode")
@Default("50")
public abstract int getSegmentsPerNode();
@Config("druid.zk.maxNumBytesPerNode")
@Default("512000")
public abstract long getMaxNumBytes();
@Config("druid.announcer.type")
@Default("legacy")
public abstract String getAnnouncerType();
}

View File

@ -1,14 +0,0 @@
package com.metamx.druid.query.group.having;
import com.metamx.druid.input.Row;
/**
*/
public class AlwaysHavingSpec implements HavingSpec
{
@Override
public boolean eval(Row row)
{
return true;
}
}

View File

@ -1,30 +0,0 @@
package com.metamx.druid.query.group.orderby;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.metamx.common.guava.Sequence;
import com.metamx.druid.aggregation.AggregatorFactory;
import com.metamx.druid.aggregation.post.PostAggregator;
import com.metamx.druid.input.Row;
import com.metamx.druid.query.dimension.DimensionSpec;
import java.util.List;
/**
*/
public class NoopLimitSpec implements LimitSpec
{
@Override
public Function<Sequence<Row>, Sequence<Row>> build(
List<DimensionSpec> dimensions, List<AggregatorFactory> aggs, List<PostAggregator> postAggs
)
{
return Functions.identity();
}
@Override
public String toString()
{
return "NoopLimitSpec";
}
}

View File

@ -1,43 +0,0 @@
package com.metamx.druid.query.group.orderby;
import com.google.common.collect.MinMaxPriorityQueue;
import java.util.Iterator;
/**
* Utility class that supports iterating a priority queue in sorted order.
*/
class OrderedPriorityQueueItems<T> implements Iterable<T>
{
private MinMaxPriorityQueue<T> rows;
public OrderedPriorityQueueItems(MinMaxPriorityQueue<T> rows)
{
this.rows = rows;
}
@Override
public Iterator<T> iterator()
{
return new Iterator<T>() {
@Override
public boolean hasNext()
{
return !rows.isEmpty();
}
@Override
public T next()
{
return rows.poll();
}
@Override
public void remove()
{
throw new UnsupportedOperationException("Can't remove any item from an intermediary heap for orderBy/limit");
}
};
}
}

View File

@ -1,106 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.query.segment;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.joda.time.Interval;
/**
*/
public class SegmentDescriptor
{
private final Interval interval;
private final String version;
private final int partitionNumber;
@JsonCreator
public SegmentDescriptor(
@JsonProperty("itvl") Interval interval,
@JsonProperty("ver") String version,
@JsonProperty("part") int partitionNumber)
{
this.interval = interval;
this.version = version;
this.partitionNumber = partitionNumber;
}
@JsonProperty("itvl")
public Interval getInterval()
{
return interval;
}
@JsonProperty("ver")
public String getVersion()
{
return version;
}
@JsonProperty("part")
public int getPartitionNumber()
{
return partitionNumber;
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SegmentDescriptor that = (SegmentDescriptor) o;
if (partitionNumber != that.partitionNumber) {
return false;
}
if (interval != null ? !interval.equals(that.interval) : that.interval != null) {
return false;
}
if (version != null ? !version.equals(that.version) : that.version != null) {
return false;
}
return true;
}
@Override
public int hashCode()
{
int result = interval != null ? interval.hashCode() : 0;
result = 31 * result + (version != null ? version.hashCode() : 0);
result = 31 * result + partitionNumber;
return result;
}
@Override
public String toString()
{
return "SegmentDescriptor{" +
"interval=" + interval +
", version='" + version + '\'' +
", partitionNumber=" + partitionNumber +
'}';
}
}

View File

@ -1,41 +0,0 @@
package com.metamx.druid.shard;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.metamx.druid.input.InputRow;
import com.metamx.druid.partition.LinearPartitionChunk;
import com.metamx.druid.partition.PartitionChunk;
import java.util.Map;
public class LinearShardSpec implements ShardSpec {
private int partitionNum;
public LinearShardSpec() {
this(-1);
}
public LinearShardSpec(int partitionNum) {
this.partitionNum = partitionNum;
}
@JsonProperty("partitionNum")
@Override
public int getPartitionNum() {
return partitionNum;
}
@Override
public <T> PartitionChunk<T> createChunk(T obj) {
return new LinearPartitionChunk<T>(partitionNum, obj);
}
@Override
public boolean isInChunk(Map<String, String> dimensions) {
return true;
}
@Override
public boolean isInChunk(InputRow inputRow) {
return true;
}
}

View File

@ -1,45 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.shard;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.metamx.druid.input.InputRow;
import com.metamx.druid.partition.PartitionChunk;
import java.util.Map;
/**
* A Marker interface that exists to combine ShardSpec objects together for Jackson
*/
@JsonTypeInfo(use= JsonTypeInfo.Id.NAME, property="type", include=JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(name="single", value=SingleDimensionShardSpec.class),
@JsonSubTypes.Type(name="none", value=NoneShardSpec.class),
@JsonSubTypes.Type(name="linear", value=LinearShardSpec.class),
@JsonSubTypes.Type(name="numbered", value=NumberedShardSpec.class)
})
public interface ShardSpec
{
public <T> PartitionChunk<T> createChunk(T obj);
public boolean isInChunk(Map<String, String> dimensions);
public boolean isInChunk(InputRow inputRow);
public int getPartitionNum();
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Druid - a distributed column store.
~ Copyright (C) 2012 Metamarkets Group Inc.
~ 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
@ -28,7 +28,7 @@
<parent>
<groupId>com.metamx</groupId>
<artifactId>druid</artifactId>
<version>0.5.59-SNAPSHOT</version>
<version>0.6.0-SNAPSHOT</version>
</parent>
<dependencies>
@ -36,6 +36,10 @@
<groupId>com.metamx</groupId>
<artifactId>java-util</artifactId>
</dependency>
<dependency>
<groupId>io.druid</groupId>
<artifactId>druid-api</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
@ -63,6 +67,14 @@
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>it.uniroma3.mat</groupId>
<artifactId>extendedset</artifactId>
@ -87,6 +99,18 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
</dependency>
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi</artifactId>

View File

@ -0,0 +1,37 @@
package com.fasterxml.jackson.databind.introspect;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.google.inject.BindingAnnotation;
import com.google.inject.Key;
import com.metamx.common.IAE;
import java.lang.annotation.Annotation;
/**
*/
public class GuiceAnnotationIntrospector extends NopAnnotationIntrospector
{
@Override
public Object findInjectableValueId(AnnotatedMember m)
{
if (m.getAnnotation(JacksonInject.class) == null) {
return null;
}
Annotation guiceAnnotation = null;
for (Annotation annotation : m.getAllAnnotations()._annotations.values()) {
if (annotation.annotationType().isAnnotationPresent(BindingAnnotation.class)) {
guiceAnnotation = annotation;
break;
}
}
if (guiceAnnotation == null) {
if (m instanceof AnnotatedMethod) {
throw new IAE("Annotated methods don't work very well yet...");
}
return Key.get(m.getGenericType());
}
return Key.get(m.getGenericType(), guiceAnnotation);
}
}

View File

@ -0,0 +1,24 @@
package com.fasterxml.jackson.databind.introspect;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.InjectableValues;
import com.google.inject.Injector;
import com.google.inject.Key;
/**
*/
public class GuiceInjectableValues extends InjectableValues
{
private final Injector injector;
public GuiceInjectableValues(Injector injector) {this.injector = injector;}
@Override
public Object findInjectableValue(
Object valueId, DeserializationContext ctxt, BeanProperty forProperty, Object beanInstance
)
{
return injector.getInstance((Key) valueId);
}
}

View File

@ -1,8 +0,0 @@
package com.metamx.druid;
import org.joda.time.Interval;
public interface LogicalSegment
{
public Interval getInterval();
}

View File

@ -1,18 +0,0 @@
package com.metamx.druid.config;
import org.joda.time.Duration;
import org.skife.config.Config;
import org.skife.config.Default;
/**
*/
public abstract class ConfigManagerConfig
{
@Config("druid.database.configTable")
public abstract String getConfigTable();
@Config("druid.indexer.poll.duration")
@Default("PT1M")
public abstract Duration getPollDuration();
}

View File

@ -1,9 +0,0 @@
package com.metamx.druid.config;
/**
*/
public interface ConfigSerde<T>
{
public byte[] serialize(T obj);
public T deserialize(byte[] bytes);
}

View File

@ -1,56 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.annotation.JsonProperty;
import org.skife.config.Config;
/**
*/
public abstract class DbConnectorConfig
{
@JsonProperty("connectURI")
@Config("druid.database.connectURI")
public abstract String getDatabaseConnectURI();
@JsonProperty("user")
@Config("druid.database.user")
public abstract String getDatabaseUser();
@JsonProperty("password")
@Config("druid.database.password")
public abstract String getDatabasePassword();
@JsonProperty("segmentTable")
@Config("druid.database.segmentTable")
public abstract String getSegmentTable();
@JsonProperty("useValidationQuery")
@Config("druid.database.validation")
public boolean useValidationQuery() {
return false;
}
@JsonProperty("validationQuery")
@Config("druid.database.validationQuery")
public String getValidationQuery() {
return "SELECT 1";
}
}

View File

@ -1,46 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.input;
import java.util.List;
/**
* An InputRow is the interface definition of an event being input into the data ingestion layer.
*
* An InputRow is a Row with a self-describing list of the dimensions available. This list is used to
* implement "schema-less" data ingestion that allows the system to add new dimensions as they appear.
*
* Note, Druid is a case-insensitive system for parts of schema (column names), this has direct implications
* for the implementation of InputRows and Rows. The case-insensitiveness is implemented by lowercasing all
* schema elements before looking them up, this means that calls to getDimension() and getFloatMetric() will
* have all lowercase column names passed in no matter what is returned from getDimensions or passed in as the
* fieldName of an AggregatorFactory. Implementations of InputRow and Row should expect to get values back
* in all lowercase form (i.e. they should either have already turned everything into lowercase or they
* should operate in a case-insensitive manner).
*/
public interface InputRow extends Row
{
/**
* Returns the dimensions that exist in this row.
*
* @return the dimensions that exist in this row.
*/
public List<String> getDimensions();
}

View File

@ -1,170 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.input;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.metamx.common.IAE;
import com.metamx.common.exception.FormattedException;
import org.joda.time.DateTime;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
*/
public class MapBasedRow implements Row
{
private final DateTime timestamp;
private final Map<String, Object> event;
@JsonCreator
public MapBasedRow(
@JsonProperty("timestamp") DateTime timestamp,
@JsonProperty("event") Map<String, Object> event
)
{
this.timestamp = timestamp;
this.event = event;
}
public MapBasedRow(
long timestamp,
Map<String, Object> event
) {
this(new DateTime(timestamp), event);
}
@Override
public long getTimestampFromEpoch()
{
return timestamp.getMillis();
}
@Override
public List<String> getDimension(String dimension)
{
Object dimValue = event.get(dimension);
if (dimValue == null) {
return Lists.newArrayList();
} else if (dimValue instanceof List) {
return Lists.transform(
(List) dimValue,
new Function<Object, String>()
{
@Override
public String apply(@Nullable Object input)
{
return String.valueOf(input);
}
}
);
} else if (dimValue instanceof Object) {
return Arrays.asList(String.valueOf(event.get(dimension)));
} else {
throw new IAE("Unknown dim type[%s]", dimValue.getClass());
}
}
@Override
public float getFloatMetric(String metric)
{
Object metricValue = event.get(metric);
if (metricValue == null) {
return 0.0f;
}
if (metricValue instanceof Number) {
return ((Number) metricValue).floatValue();
} else if (metricValue instanceof String) {
try {
return Float.valueOf(((String) metricValue).replace(",", ""));
}
catch (Exception e) {
throw new FormattedException.Builder()
.withErrorCode(FormattedException.ErrorCode.UNPARSABLE_METRIC)
.withDetails(ImmutableMap.<String, Object>of("metricName", metric, "metricValue", metricValue))
.withMessage(e.getMessage())
.build();
}
} else {
throw new IAE("Unknown type[%s]", metricValue.getClass());
}
}
@JsonProperty
public DateTime getTimestamp()
{
return timestamp;
}
@JsonProperty
public Map<String, Object> getEvent()
{
return event;
}
@Override
public String toString()
{
return "MapBasedRow{" +
"timestamp=" + timestamp +
", event=" + event +
'}';
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MapBasedRow that = (MapBasedRow) o;
if (!event.equals(that.event)) {
return false;
}
if (!timestamp.equals(that.timestamp)) {
return false;
}
return true;
}
@Override
public int hashCode()
{
int result = timestamp.hashCode();
result = 31 * result + event.hashCode();
return result;
}
}

View File

@ -1,72 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.input;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import java.util.List;
/**
* A Row of data. This can be used for both input and output into various parts of the system. It assumes
* that the user already knows the schema of the row and can query for the parts that they care about.
*
* Note, Druid is a case-insensitive system for parts of schema (column names), this has direct implications
* for the implementation of InputRows and Rows. The case-insensitiveness is implemented by lowercasing all
* schema elements before looking them up, this means that calls to getDimension() and getFloatMetric() will
* have all lowercase column names passed in no matter what is returned from getDimensions or passed in as the
* fieldName of an AggregatorFactory. Implementations of InputRow and Row should expect to get values back
* in all lowercase form (i.e. they should either have already turned everything into lowercase or they
* should operate in a case-insensitive manner).
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version")
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = "v1", value = MapBasedRow.class)
})
public interface Row
{
/**
* Returns the timestamp from the epoch in milliseconds. If the event happened _right now_, this would return the
* same thing as System.currentTimeMillis();
*
* @return the timestamp from the epoch in milliseconds.
*/
public long getTimestampFromEpoch();
/**
* Returns the list of dimension values for the given column name.
*
* Column names are always all lowercase in order to support case-insensitive schemas.
*
* @param dimension the lowercase column name of the dimension requested
* @return the list of values for the provided column name
*/
public List<String> getDimension(String dimension);
/**
* Returns the float value of the given metric column.
*
* Column names are always all lowercase in order to support case-insensitive schemas.
*
* @param metric the lowercase column name of the metric requested
* @return the float value for the provided column name.
*/
public float getFloatMetric(String metric);
}

View File

@ -1,47 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.input;
import com.google.common.collect.Maps;
import com.metamx.common.ISE;
import java.util.List;
import java.util.TreeMap;
/**
*/
public class Rows
{
public static InputRow toCaseInsensitiveInputRow(final Row row, final List<String> dimensions)
{
if (row instanceof MapBasedRow) {
MapBasedRow mapBasedRow = (MapBasedRow) row;
TreeMap<String, Object> caseInsensitiveMap = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
caseInsensitiveMap.putAll(mapBasedRow.getEvent());
return new MapBasedInputRow(
mapBasedRow.getTimestampFromEpoch(),
dimensions,
caseInsensitiveMap
);
}
throw new ISE("Can only convert MapBasedRow objects because we are ghetto like that.");
}
}

View File

@ -1,72 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.partition;
/**
* A PartitionChunk represents a chunk of a partitioned(sharded) space. It has knowledge of whether it is
* the start of the domain of partitions, the end of the domain, if it abuts another partition and where it stands
* inside of a sorted collection of partitions.
*
* The ordering of PartitionChunks is based entirely upon the partition boundaries defined inside the concrete
* PartitionChunk class. That is, the payload (the object returned by getObject()) should *not* be involved in
* comparisons between PartitionChunk objects.
*/
public interface PartitionChunk<T> extends Comparable<PartitionChunk<T>>
{
/**
* Returns the payload, generally an object that can be used to perform some action against the shard.
*
* @return the payload
*/
public T getObject();
/**
* Determines if this PartitionChunk abuts another PartitionChunk. A sequence of abutting PartitionChunks should
* start with an object where isStart() == true and eventually end with an object where isEnd() == true.
*
* @param chunk input chunk
* @return true if this chunk abuts the input chunk
*/
public boolean abuts(PartitionChunk<T> chunk);
/**
* Returns true if this chunk is the beginning of the partition. Most commonly, that means it represents the range
* [-infinity, X) for some concrete X.
*
* @return true if the chunk is the beginning of the partition
*/
public boolean isStart();
/**
* Returns true if this chunk is the end of the partition. Most commonly, that means it represents the range
* [X, infinity] for some concrete X.
*
* @return true if the chunk is the beginning of the partition
*/
public boolean isEnd();
/**
* Returns the partition chunk number of this PartitionChunk. I.e. if there are 4 partitions in total and this
* is the 3rd partition, it will return 2
*
* @return the sequential numerical id of this partition chunk
*/
public int getChunkNumber();
}

View File

@ -1,109 +0,0 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 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.partition;
/**
*/
public class SingleElementPartitionChunk<T> implements PartitionChunk<T>
{
private final T element;
public SingleElementPartitionChunk
(
T element
)
{
this.element = element;
}
@Override
public T getObject()
{
return element;
}
@Override
public boolean abuts(PartitionChunk<T> tPartitionChunk)
{
return false;
}
@Override
public boolean isStart()
{
return true;
}
@Override
public boolean isEnd()
{
return true;
}
@Override
public int getChunkNumber()
{
return 0;
}
/**
* The ordering of PartitionChunks is determined entirely by the partition boundaries and has nothing to do
* with the object. Thus, if there are two SingleElementPartitionChunks, they are equal because they both
* represent the full partition space.
*
* SingleElementPartitionChunks are currently defined as less than every other type of PartitionChunk. There
* is no good reason for it, nor is there a bad reason, that's just the way it is. This is subject to change.
*
* @param chunk
* @return
*/
@Override
public int compareTo(PartitionChunk<T> chunk)
{
return chunk instanceof SingleElementPartitionChunk ? 0 : -1;
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
return true;
}
@Override
public int hashCode()
{
return element != null ? element.hashCode() : 0;
}
@Override
public String toString()
{
return "SingleElementPartitionChunk{" +
"element=" + element +
'}';
}
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.collections;
import com.metamx.common.guava.MergeIterable;
import com.metamx.common.guava.nary.BinaryFn;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.collections;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.collections;
import java.nio.IntBuffer;
import java.util.ArrayList;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import com.google.common.base.Function;
import com.google.common.base.Predicate;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import com.google.common.base.Function;
import com.google.common.base.Throwables;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import java.io.Closeable;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import java.io.IOException;

View File

@ -1,11 +1,33 @@
package com.metamx.druid.config;
/*
* 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 io.druid.common.config;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
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 io.druid.db.DbTablesConfig;
import org.joda.time.Duration;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.IDBI;
@ -33,7 +55,7 @@ public class ConfigManager
private boolean started = false;
private final IDBI dbi;
private final ConfigManagerConfig config;
private final Supplier<ConfigManagerConfig> config;
private final ScheduledExecutorService exec;
private final ConcurrentMap<String, ConfigHolder> watchedConfigs;
@ -42,17 +64,21 @@ public class ConfigManager
private volatile ConfigManager.PollingCallable poller;
public ConfigManager(IDBI dbi, ConfigManagerConfig config)
@Inject
public ConfigManager(IDBI dbi, Supplier<DbTablesConfig> dbTables, Supplier<ConfigManagerConfig> 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
);
}
@ -65,7 +91,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;
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,22 +17,23 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.coordination;
package io.druid.common.config;
import org.skife.config.Config;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.joda.time.Period;
import java.io.File;
import javax.validation.constraints.NotNull;
/**
*/
public abstract class ZkCoordinatorConfig
public class ConfigManagerConfig
{
@Config("druid.paths.segmentInfoCache")
public abstract File getSegmentInfoCacheDirectory();
@JsonProperty
@NotNull
private Period pollDuration = new Period("PT1M");
@Config("druid.segmentCache.enable")
public boolean isLoadFromSegmentCacheEnabled()
public Period getPollDuration()
{
return true;
return pollDuration;
}
}

View File

@ -0,0 +1,28 @@
/*
* 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 io.druid.common.config;
/**
*/
public interface ConfigSerde<T>
{
public byte[] serialize(T obj);
public T deserialize(byte[] bytes);
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,12 +17,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.config;
package io.druid.common.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Throwables;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
@ -34,6 +35,7 @@ public class JacksonConfigManager
private final ConfigManager configManager;
private final ObjectMapper jsonMapper;
@Inject
public JacksonConfigManager(
ConfigManager configManager,
ObjectMapper jsonMapper

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
import com.google.common.collect.Ordering;
import com.metamx.common.guava.Accumulator;

View File

@ -0,0 +1,41 @@
/*
* 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 io.druid.common.guava;
import com.google.common.base.Supplier;
import java.util.concurrent.atomic.AtomicReference;
/**
*/
public class DSuppliers
{
public static <T> Supplier<T> of(final AtomicReference<T> ref)
{
return new Supplier<T>()
{
@Override
public T get()
{
return ref.get();
}
};
}
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
import com.google.common.io.OutputSupplier;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
import com.google.common.base.Charsets;
import com.google.common.base.Function;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
/**
*/

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
import java.util.concurrent.Callable;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
/**
*/

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.utils;
package io.druid.common.utils;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.utils;
package io.druid.common.utils;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.utils;
package io.druid.common.utils;
import com.metamx.common.ISE;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,12 +17,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.utils;
package io.druid.common.utils;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.OutputSupplier;
import com.metamx.druid.IntList;
import io.druid.collections.IntList;
import java.io.IOException;
import java.io.InputStream;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,30 +17,42 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.jackson;
package io.druid.common.utils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.metamx.common.ISE;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.net.ServerSocket;
/**
*/
public class CommaListJoinDeserializer extends StdScalarDeserializer<List<String>>
public class SocketUtil
{
protected CommaListJoinDeserializer()
public static int findOpenPort(int startPort)
{
super(List.class);
int currPort = startPort;
while (currPort < 0xffff) {
ServerSocket socket = null;
try {
socket = new ServerSocket(currPort);
return currPort;
}
catch (IOException e) {
++currPort;
}
finally {
if (socket != null) {
try {
socket.close();
}
catch (IOException e) {
}
}
}
}
@Override
public List<String> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException
{
return Arrays.asList(jsonParser.getText().split(","));
throw new ISE("Unable to find open port between[%d] and [%d]", startPort, currPort);
}
}

View File

@ -0,0 +1,52 @@
/*
* 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 io.druid.concurrent;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
/**
*/
public class Execs
{
public static ExecutorService singleThreaded(String nameFormat)
{
return Executors.newSingleThreadExecutor(makeThreadFactory(nameFormat));
}
public static ExecutorService multiThreaded(int threads, String nameFormat)
{
return Executors.newFixedThreadPool(threads, makeThreadFactory(nameFormat));
}
public static ScheduledExecutorService scheduledSingleThreaded(String nameFormat)
{
return Executors.newSingleThreadScheduledExecutor(makeThreadFactory(nameFormat));
}
public static ThreadFactory makeThreadFactory(String nameFormat)
{
return new ThreadFactoryBuilder().setDaemon(true).setNameFormat(nameFormat).build();
}
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,12 +17,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.db;
package io.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;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.IDBI;
import org.skife.jdbi.v2.tweak.HandleCallback;
import javax.sql.DataSource;
@ -35,7 +38,7 @@ public class DbConnector
{
private static final Logger log = new Logger(DbConnector.class);
public static void createSegmentTable(final DBI dbi, final String segmentTableName)
public static void createSegmentTable(final IDBI dbi, final String segmentTableName)
{
createTable(
dbi,
@ -47,7 +50,7 @@ public class DbConnector
);
}
public static void createRuleTable(final DBI dbi, final String ruleTableName)
public static void createRuleTable(final IDBI dbi, final String ruleTableName)
{
createTable(
dbi,
@ -59,7 +62,7 @@ public class DbConnector
);
}
public static void createConfigTable(final DBI dbi, final String configTableName)
public static void createConfigTable(final IDBI dbi, final String configTableName)
{
createTable(
dbi,
@ -71,7 +74,7 @@ public class DbConnector
);
}
public static void createTaskTable(final DBI dbi, final String taskTableName)
public static void createTaskTable(final IDBI dbi, final String taskTableName)
{
createTable(
dbi,
@ -91,7 +94,7 @@ public class DbConnector
);
}
public static void createTaskLogTable(final DBI dbi, final String taskLogsTableName)
public static void createTaskLogTable(final IDBI dbi, final String taskLogsTableName)
{
createTable(
dbi,
@ -109,7 +112,7 @@ public class DbConnector
);
}
public static void createTaskLockTable(final DBI dbi, final String taskLocksTableName)
public static void createTaskLockTable(final IDBI dbi, final String taskLocksTableName)
{
createTable(
dbi,
@ -128,7 +131,7 @@ public class DbConnector
}
public static void createTable(
final DBI dbi,
final IDBI dbi,
final String tableName,
final String sql
)
@ -160,12 +163,15 @@ public class DbConnector
}
}
private final DbConnectorConfig config;
private final Supplier<DbConnectorConfig> config;
private final Supplier<DbTablesConfig> dbTables;
private final DBI dbi;
public DbConnector(DbConnectorConfig config)
@Inject
public DbConnector(Supplier<DbConnectorConfig> config, Supplier<DbTablesConfig> dbTables)
{
this.config = config;
this.dbTables = dbTables;
this.dbi = new DBI(getDatasource());
}
@ -177,16 +183,49 @@ public class DbConnector
private DataSource getDatasource()
{
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUsername(config.getDatabaseUser());
dataSource.setPassword(config.getDatabasePassword());
dataSource.setUrl(config.getDatabaseConnectURI());
DbConnectorConfig connectorConfig = config.get();
if (config.useValidationQuery()) {
dataSource.setValidationQuery(config.getValidationQuery());
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUsername(connectorConfig.getUser());
dataSource.setPassword(connectorConfig.getPassword());
dataSource.setUrl(connectorConfig.getConnectURI());
if (connectorConfig.isUseValidationQuery()) {
dataSource.setValidationQuery(connectorConfig.getValidationQuery());
dataSource.setTestOnBorrow(true);
}
return dataSource;
}
public void createSegmentTable()
{
if (config.get().isCreateTables()) {
createSegmentTable(dbi, dbTables.get().getSegmentsTable());
}
}
public void createRulesTable()
{
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());
}
}
}

View File

@ -0,0 +1,92 @@
/*
* 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 io.druid.db;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotNull;
/**
*/
public class DbConnectorConfig
{
@JsonProperty
private boolean createTables = true;
@JsonProperty
@NotNull
private String connectURI = null;
@JsonProperty
@NotNull
private String user = null;
@JsonProperty
@NotNull
private String password = null;
@JsonProperty
private boolean useValidationQuery = false;
@JsonProperty
private String validationQuery = "SELECT 1";
public boolean isCreateTables()
{
return createTables;
}
public String getConnectURI()
{
return connectURI;
}
public String getUser()
{
return user;
}
public String getPassword()
{
return password;
}
public boolean isUseValidationQuery()
{
return useValidationQuery;
}
public String getValidationQuery() {
return validationQuery;
}
@Override
public String toString()
{
return "DbConnectorConfig{" +
"createTables=" + createTables +
", connectURI='" + connectURI + '\'' +
", user='" + user + '\'' +
", password=****" +
", useValidationQuery=" + useValidationQuery +
", validationQuery='" + validationQuery + '\'' +
'}';
}
}

View File

@ -0,0 +1,124 @@
/*
* 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 io.druid.db;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotNull;
/**
*/
public class DbTablesConfig
{
public static DbTablesConfig fromBase(String base)
{
return new DbTablesConfig(base, null, null, null, null, null, null);
}
@JsonProperty
@NotNull
private final String base;
@JsonProperty("segments")
private final String segmentsTable;
@JsonProperty("rules")
private final String rulesTable;
@JsonProperty("config")
private final String configTable;
@JsonProperty("tasks")
private final String tasksTable;
@JsonProperty("taskLog")
private final String taskLogTable;
@JsonProperty("taskLock")
private final String taskLockTable;
@JsonCreator
public DbTablesConfig(
@JsonProperty("base") String base,
@JsonProperty("segments") String segmentsTable,
@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.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)
{
if (explicitTableName == null) {
if (base == null) {
return null;
}
return String.format("%s_%s", base, defaultSuffix);
}
return explicitTableName;
}
public String getBase()
{
return base;
}
public String getSegmentsTable()
{
return segmentsTable;
}
public String getRulesTable()
{
return rulesTable;
}
public String getConfigTable()
{
return configTable;
}
public String getTasksTable()
{
return tasksTable;
}
public String getTaskLogTable()
{
return taskLogTable;
}
public String getTaskLockTable()
{
return taskLockTable;
}
}

View File

@ -0,0 +1,89 @@
/*
* 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 io.druid.guice;
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;
import java.util.Map;
/**
*/
public class ConfigProvider<T> implements Provider<T>
{
private static final Logger log = new Logger(ConfigProvider.class);
public static <T> void bind(Binder binder, Class<T> clazz)
{
binder.bind(clazz).toProvider(of(clazz)).in(LazySingleton.class);
}
public static <T> void bind(Binder binder, Class<T> clazz, Map<String, String> replacements)
{
binder.bind(clazz).toProvider(of(clazz, replacements)).in(LazySingleton.class);
}
public static <T> Provider<T> of(Class<T> clazz)
{
return of(clazz, null);
}
public static <T> Provider<T> of(Class<T> clazz, Map<String, String> replacements)
{
return new ConfigProvider<T>(clazz, replacements);
}
private final Class<T> clazz;
private final Map<String, String> replacements;
private T object = null;
public ConfigProvider(
Class<T> clazz,
Map<String, String> replacements
)
{
this.clazz = clazz;
this.replacements = replacements;
}
@Inject
public void inject(ConfigurationObjectFactory factory)
{
try {
// ConfigMagic handles a null replacements
object = factory.buildWithReplacements(clazz, replacements);
}
catch (IllegalArgumentException e) {
log.info("Unable to build instance of class[%s]", clazz);
throw e;
}
}
@Override
public T get()
{
return Preconditions.checkNotNull(object, "WTF!? Code misconfigured, inject() didn't get called.");
}
}

View File

@ -0,0 +1,48 @@
/*
* 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 io.druid.guice;
import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Provides;
import io.druid.db.DbConnector;
import io.druid.db.DbConnectorConfig;
import io.druid.db.DbTablesConfig;
import org.skife.jdbi.v2.IDBI;
/**
*/
public class DbConnectorModule implements Module
{
@Override
public void configure(Binder binder)
{
JsonConfigProvider.bind(binder, "druid.db.tables", DbTablesConfig.class);
JsonConfigProvider.bind(binder, "druid.db.connector", DbConnectorConfig.class);
binder.bind(DbConnector.class);
}
@Provides @LazySingleton
public IDBI getDbi(final DbConnector dbConnector)
{
return dbConnector.getDBI();
}
}

View File

@ -0,0 +1,107 @@
/*
* 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 io.druid.guice;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.databind.introspect.GuiceAnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.GuiceInjectableValues;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provides;
import io.druid.guice.annotations.Json;
import io.druid.guice.annotations.Smile;
import org.skife.config.ConfigurationObjectFactory;
import javax.validation.Validator;
import java.util.Properties;
/**
*/
public class DruidSecondaryModule implements Module
{
private final Properties properties;
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,
Validator validator,
JsonConfigurator jsonConfigurator
)
{
this.properties = properties;
this.factory = factory;
this.jsonMapper = jsonMapper;
this.smileMapper = smileMapper;
this.validator = validator;
this.jsonConfigurator = jsonConfigurator;
}
@Override
public void configure(Binder binder)
{
binder.requireExplicitBindings();
binder.install(new DruidGuiceExtensions());
binder.bind(Properties.class).toInstance(properties);
binder.bind(ConfigurationObjectFactory.class).toInstance(factory);
binder.bind(ObjectMapper.class).to(Key.get(ObjectMapper.class, Json.class));
binder.bind(Validator.class).toInstance(validator);
binder.bind(JsonConfigurator.class).toInstance(jsonConfigurator);
}
@Provides @LazySingleton @Json
public ObjectMapper getJsonMapper(final Injector injector)
{
setupJackson(injector, jsonMapper);
return jsonMapper;
}
@Provides @LazySingleton @Smile
public ObjectMapper getSmileMapper(Injector injector)
{
setupJackson(injector, smileMapper);
return smileMapper;
}
private void setupJackson(Injector injector, final ObjectMapper mapper) {
final GuiceAnnotationIntrospector guiceIntrospector = new GuiceAnnotationIntrospector();
mapper.setInjectableValues(new GuiceInjectableValues(injector));
mapper.setAnnotationIntrospectors(
new AnnotationIntrospectorPair(
guiceIntrospector, mapper.getSerializationConfig().getAnnotationIntrospector()
),
new AnnotationIntrospectorPair(
guiceIntrospector, mapper.getDeserializationConfig().getAnnotationIntrospector()
)
);
}
}

View File

@ -0,0 +1,71 @@
/*
* 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 io.druid.guice;
import com.google.common.base.Supplier;
import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.metamx.common.lifecycle.Lifecycle;
import io.druid.common.config.ConfigManager;
import io.druid.common.config.ConfigManagerConfig;
import io.druid.common.config.JacksonConfigManager;
import io.druid.db.DbConnector;
import io.druid.db.DbTablesConfig;
/**
*/
public class JacksonConfigManagerModule implements Module
{
@Override
public void configure(Binder binder)
{
JsonConfigProvider.bind(binder, "druid.manager.config", ConfigManagerConfig.class);
binder.bind(JacksonConfigManager.class).in(LazySingleton.class);
}
@Provides @ManageLifecycle
public ConfigManager getConfigManager(
final DbConnector dbConnector,
final Supplier<DbTablesConfig> dbTables,
final Supplier<ConfigManagerConfig> config,
final Lifecycle lifecycle
)
{
lifecycle.addHandler(
new Lifecycle.Handler()
{
@Override
public void start() throws Exception
{
dbConnector.createConfigTable();
}
@Override
public void stop()
{
}
}
);
return new ConfigManager(dbConnector.getDBI(), dbTables, config);
}
}

View File

@ -0,0 +1,94 @@
/*
* 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 io.druid.guice;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Supplier;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.util.Types;
import io.druid.common.config.JacksonConfigManager;
import io.druid.common.guava.DSuppliers;
/**
*/
public class JacksonConfigProvider<T> implements Provider<Supplier<T>>
{
public static <T> void bind(Binder binder, String key, Class<T> clazz, T defaultVal)
{
binder.bind(Key.get(Types.newParameterizedType(Supplier.class, clazz)))
.toProvider((Provider) of(key, clazz, defaultVal))
.in(LazySingleton.class);
}
public static <T> JacksonConfigProvider<T> of(String key, Class<T> clazz)
{
return of(key, clazz, null);
}
public static <T> JacksonConfigProvider<T> of(String key, Class<T> clazz, T defaultVal)
{
return new JacksonConfigProvider<T>(key, clazz, null, defaultVal);
}
public static <T> JacksonConfigProvider<T> of(String key, TypeReference<T> clazz)
{
return of(key, clazz, null);
}
public static <T> JacksonConfigProvider<T> of(String key, TypeReference<T> typeRef, T defaultVal)
{
return new JacksonConfigProvider<T>(key, null, typeRef, defaultVal);
}
private final String key;
private final Class<T> clazz;
private final TypeReference<T> typeRef;
private final T defaultVal;
private JacksonConfigManager configManager;
JacksonConfigProvider(String key, Class<T> clazz, TypeReference<T> typeRef, T defaultVal)
{
this.key = key;
this.clazz = clazz;
this.typeRef = typeRef;
this.defaultVal = defaultVal;
}
@Inject
public void configure(JacksonConfigManager configManager)
{
this.configManager = configManager;
}
@Override
public Supplier<T> get()
{
if (clazz == null) {
return DSuppliers.of(configManager.watch(key, typeRef, defaultVal));
}
else {
return DSuppliers.of(configManager.watch(key, clazz, defaultVal));
}
}
}

View File

@ -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 io.druid.guice;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
import java.lang.annotation.Annotation;
import java.util.List;
/**
*/
public class ListProvider<T> implements Provider<List<T>>
{
private final List<Key<? extends T>> itemsToLoad = Lists.newArrayList();
private Injector injector;
public ListProvider<T> add(Class<? extends T> clazz)
{
return add(Key.get(clazz));
}
public ListProvider<T> add(Class<? extends T> clazz, Class<? extends Annotation> annotation)
{
return add(Key.get(clazz, annotation));
}
public ListProvider<T> add(Class<? extends T> clazz, Annotation annotation)
{
return add(Key.get(clazz, annotation));
}
public ListProvider<T> add(Key<? extends T> key)
{
itemsToLoad.add(key);
return this;
}
@Inject
private void configure(Injector injector)
{
this.injector = injector;
}
@Override
public List<T> get()
{
List<T> retVal = Lists.newArrayListWithExpectedSize(itemsToLoad.size());
for (Key<? extends T> key : itemsToLoad) {
retVal.add(injector.getInstance(key));
}
return retVal;
}
}

View File

@ -0,0 +1,157 @@
/*
* 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 io.druid.guice;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.util.Types;
import javax.annotation.Nullable;
import java.lang.reflect.ParameterizedType;
import java.util.Map;
import java.util.Properties;
/**
* Provides the ability to create "polymorphic" bindings. Where the polymorphism is actually just making a decision
* based on a value in a Properties.
*
* The workflow is that you first create a choice by calling createChoice(). Then you create options using the binder
* returned by the optionBinder() method. Multiple different modules can call optionBinder and all options will be
* reflected at injection time as long as equivalent interface Key objects are passed into the various methods.
*/
public class PolyBind
{
/**
* Sets up a "choice" for the injector to resolve at injection time.
*
* @param binder the binder for the injector that is being configured
* @param property the property that will be checked to determine the implementation choice
* @param interfaceKey the interface that will be injected using this choice
* @param defaultKey the default instance to be injected if the property doesn't match a choice. Can be null
* @param <T> interface type
* @return A ScopedBindingBuilder so that scopes can be added to the binding, if required.
*/
public static <T> ScopedBindingBuilder createChoice(
Binder binder,
String property,
Key<T> interfaceKey,
@Nullable Key<? extends T> defaultKey
)
{
return binder.bind(interfaceKey).toProvider(new ConfiggedProvider<T>(interfaceKey, property, defaultKey));
}
/**
* Binds an option for a specific choice. The choice must already be registered on the injector for this to work.
*
* @param binder the binder for the injector that is being configured
* @param interfaceKey the interface that will have an option added to it. This must equal the
* Key provided to createChoice
* @param <T> interface type
* @return A MapBinder that can be used to create the actual option bindings.
*/
public static <T> MapBinder<String, T> optionBinder(Binder binder, Key<T> interfaceKey)
{
final TypeLiteral<T> interfaceType = interfaceKey.getTypeLiteral();
if (interfaceKey.getAnnotation() != null) {
return MapBinder.newMapBinder(
binder, TypeLiteral.get(String.class), interfaceType, interfaceKey.getAnnotation()
);
}
else if (interfaceKey.getAnnotationType() != null) {
return MapBinder.newMapBinder(
binder, TypeLiteral.get(String.class), interfaceType, interfaceKey.getAnnotationType()
);
}
else {
return MapBinder.newMapBinder(binder, TypeLiteral.get(String.class), interfaceType);
}
}
static class ConfiggedProvider<T> implements Provider<T>
{
private final Key<T> key;
private final String property;
private final Key<? extends T> defaultKey;
private Injector injector;
private Properties props;
ConfiggedProvider(
Key<T> key,
String property,
Key<? extends T> defaultKey
)
{
this.key = key;
this.property = property;
this.defaultKey = defaultKey;
}
@Inject
void configure(Injector injector, Properties props)
{
this.injector = injector;
this.props = props;
}
@Override
@SuppressWarnings("unchecked")
public T get()
{
final ParameterizedType mapType = Types.mapOf(
String.class, Types.newParameterizedType(Provider.class, key.getTypeLiteral().getType())
);
final Map<String, Provider<T>> implsMap;
if (key.getAnnotation() != null) {
implsMap = (Map<String, Provider<T>>) injector.getInstance(Key.get(mapType, key.getAnnotation()));
}
else if (key.getAnnotationType() != null) {
implsMap = (Map<String, Provider<T>>) injector.getInstance(Key.get(mapType, key.getAnnotation()));
}
else {
implsMap = (Map<String, Provider<T>>) injector.getInstance(Key.get(mapType));
}
final String implName = props.getProperty(property);
final Provider<T> provider = implsMap.get(implName);
if (provider == null) {
if (defaultKey == null) {
throw new ProvisionException(
String.format("Unknown provider[%s] of %s, known options[%s]", implName, key, implsMap.keySet())
);
}
return injector.getInstance(defaultKey);
}
return provider.get();
}
}
}

View File

@ -0,0 +1,27 @@
/*
* 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 io.druid.timeline;
import org.joda.time.Interval;
public interface LogicalSegment
{
public Interval getInterval();
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,9 +17,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.timeline;
import com.metamx.druid.partition.PartitionHolder;
import io.druid.timeline.partition.PartitionHolder;
import org.joda.time.Interval;
/**

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,15 +17,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.timeline;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.metamx.common.guava.Comparators;
import com.metamx.common.logger.Logger;
import com.metamx.druid.partition.ImmutablePartitionHolder;
import com.metamx.druid.partition.PartitionChunk;
import com.metamx.druid.partition.PartitionHolder;
import io.druid.timeline.partition.ImmutablePartitionHolder;
import io.druid.timeline.partition.PartitionChunk;
import io.druid.timeline.partition.PartitionHolder;
import org.joda.time.DateTime;
import org.joda.time.Interval;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
/**
*/

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
import com.google.common.collect.Ordering;

View File

@ -1,4 +1,23 @@
package com.metamx.druid.partition;
/*
* 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 io.druid.timeline.partition;
import com.google.common.collect.Ordering;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
import com.google.common.base.Function;
import com.google.common.base.Predicate;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
import com.google.common.collect.Ordering;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.collections;
import org.junit.Assert;
import org.junit.Test;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import java.util.Iterator;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.collect;
package io.druid.collections;
import com.google.common.base.Function;
import com.google.common.collect.Lists;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.guava;
package io.druid.common.guava;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.utils;
package io.druid.common.utils;
import org.joda.time.Interval;
import org.junit.Assert;

View File

@ -0,0 +1,250 @@
/*
* 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 io.druid.guice;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.metamx.common.lifecycle.Lifecycle;
import com.metamx.common.lifecycle.LifecycleStart;
import com.metamx.common.lifecycle.LifecycleStop;
import junit.framework.Assert;
import org.junit.Test;
/**
*/
public class LifecycleScopeTest
{
@Test
public void testAnnotation() throws Exception
{
final Injector injector = Guice.createInjector(
new DruidGuiceExtensions(),
new LifecycleModule(),
new Module()
{
@Override
public void configure(Binder binder)
{
binder.bind(TestInterface.class).to(AnnotatedClass.class);
}
}
);
final Lifecycle lifecycle = injector.getInstance(Lifecycle.class);
final TestInterface instance = injector.getInstance(TestInterface.class);
testIt(injector, lifecycle, instance);
}
@Test
public void testExplicit() throws Exception
{
final Injector injector = Guice.createInjector(
new DruidGuiceExtensions(),
new LifecycleModule(),
new Module()
{
@Override
public void configure(Binder binder)
{
binder.bind(TestInterface.class).to(ExplicitClass.class).in(ManageLifecycle.class);
}
}
);
final Lifecycle lifecycle = injector.getInstance(Lifecycle.class);
final TestInterface instance = injector.getInstance(TestInterface.class);
testIt(injector, lifecycle, instance);
}
private void testIt(Injector injector, Lifecycle lifecycle, TestInterface instance)
throws Exception
{
Assert.assertEquals(0, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(0, instance.getRan());
instance.run();
Assert.assertEquals(0, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(1, instance.getRan());
lifecycle.start();
Assert.assertEquals(1, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(1, instance.getRan());
injector.getInstance(TestInterface.class).run(); // It's a singleton
Assert.assertEquals(1, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(2, instance.getRan());
lifecycle.stop();
Assert.assertEquals(1, instance.getStarted());
Assert.assertEquals(1, instance.getStopped());
Assert.assertEquals(2, instance.getRan());
}
/**
* This is a test for documentation purposes. It's there to show what weird things Guice will do when
* it sees both the annotation and an explicit binding.
*
* @throws Exception
*/
@Test
public void testAnnotatedAndExplicit() throws Exception
{
final Injector injector = Guice.createInjector(
new DruidGuiceExtensions(),
new LifecycleModule(),
new Module()
{
@Override
public void configure(Binder binder)
{
binder.bind(TestInterface.class).to(AnnotatedClass.class).in(ManageLifecycle.class);
}
}
);
final Lifecycle lifecycle = injector.getInstance(Lifecycle.class);
final TestInterface instance = injector.getInstance(TestInterface.class);
Assert.assertEquals(0, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(0, instance.getRan());
instance.run();
Assert.assertEquals(0, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(1, instance.getRan());
lifecycle.start();
Assert.assertEquals(2, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(1, instance.getRan());
injector.getInstance(TestInterface.class).run(); // It's a singleton
Assert.assertEquals(2, instance.getStarted());
Assert.assertEquals(0, instance.getStopped());
Assert.assertEquals(2, instance.getRan());
lifecycle.stop();
Assert.assertEquals(2, instance.getStarted());
Assert.assertEquals(2, instance.getStopped());
Assert.assertEquals(2, instance.getRan());
}
private static interface TestInterface
{
public void run();
public int getStarted();
public int getStopped();
public int getRan();
}
@ManageLifecycle
public static class AnnotatedClass implements TestInterface
{
int started = 0;
int stopped = 0;
int ran = 0;
@LifecycleStart
public void start()
{
++started;
}
@LifecycleStop
public void stop()
{
++stopped;
}
@Override
public void run()
{
++ran;
}
public int getStarted()
{
return started;
}
public int getStopped()
{
return stopped;
}
public int getRan()
{
return ran;
}
}
public static class ExplicitClass implements TestInterface
{
int started = 0;
int stopped = 0;
int ran = 0;
@LifecycleStart
public void start()
{
++started;
}
@LifecycleStop
public void stop()
{
++stopped;
}
@Override
public void run()
{
++ran;
}
public int getStarted()
{
return started;
}
public int getStopped()
{
return stopped;
}
public int getRan()
{
return ran;
}
}
}

View File

@ -0,0 +1,128 @@
/*
* 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 io.druid.guice;
import com.google.common.collect.Iterables;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.name.Names;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.Properties;
/**
*/
public class PolyBindTest
{
private Properties props;
private Injector injector;
public void setUp(Module... modules) throws Exception
{
props = new Properties();
injector = Guice.createInjector(
Iterables.concat(
Arrays.asList(
new Module()
{
@Override
public void configure(Binder binder)
{
binder.bind(Properties.class).toInstance(props);
PolyBind.createChoice(binder, "billy", Key.get(Gogo.class), Key.get(GoA.class));
}
}
),
Arrays.asList(modules)
)
);
}
@Test
public void testSanity() throws Exception
{
setUp(
new Module()
{
@Override
public void configure(Binder binder)
{
final MapBinder<String,Gogo> gogoBinder = PolyBind.optionBinder(binder, Key.get(Gogo.class));
gogoBinder.addBinding("a").to(GoA.class);
gogoBinder.addBinding("b").to(GoB.class);
PolyBind.createChoice(
binder, "billy", Key.get(Gogo.class, Names.named("reverse")), Key.get(GoB.class)
);
final MapBinder<String,Gogo> annotatedGogoBinder = PolyBind.optionBinder(
binder, Key.get(Gogo.class, Names.named("reverse"))
);
annotatedGogoBinder.addBinding("a").to(GoB.class);
annotatedGogoBinder.addBinding("b").to(GoA.class);
}
}
);
Assert.assertEquals("A", injector.getInstance(Gogo.class).go());
Assert.assertEquals("B", injector.getInstance(Key.get(Gogo.class, Names.named("reverse"))).go());
props.setProperty("billy", "b");
Assert.assertEquals("B", injector.getInstance(Gogo.class).go());
Assert.assertEquals("A", injector.getInstance(Key.get(Gogo.class, Names.named("reverse"))).go());
props.setProperty("billy", "a");
Assert.assertEquals("A", injector.getInstance(Gogo.class).go());
Assert.assertEquals("B", injector.getInstance(Key.get(Gogo.class, Names.named("reverse"))).go());
props.setProperty("billy", "b");
Assert.assertEquals("B", injector.getInstance(Gogo.class).go());
Assert.assertEquals("A", injector.getInstance(Key.get(Gogo.class, Names.named("reverse"))).go());
props.setProperty("billy", "c");
Assert.assertEquals("A", injector.getInstance(Gogo.class).go());
Assert.assertEquals("B", injector.getInstance(Key.get(Gogo.class, Names.named("reverse"))).go());
}
public static interface Gogo
{
public String go();
}
public static class GoA implements Gogo
{
@Override
public String go()
{
return "A";
}
}
public static class GoB implements Gogo
{
@Override
public String go()
{
return "B";
}
}
}

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,16 +17,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid;
package io.druid.timeline;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import com.metamx.common.Pair;
import com.metamx.druid.partition.ImmutablePartitionHolder;
import com.metamx.druid.partition.IntegerPartitionChunk;
import com.metamx.druid.partition.PartitionChunk;
import com.metamx.druid.partition.PartitionHolder;
import com.metamx.druid.partition.SingleElementPartitionChunk;
import io.druid.timeline.partition.ImmutablePartitionHolder;
import io.druid.timeline.partition.IntegerPartitionChunk;
import io.druid.timeline.partition.PartitionChunk;
import io.druid.timeline.partition.PartitionHolder;
import io.druid.timeline.partition.SingleElementPartitionChunk;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Hours;

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,12 +17,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
import org.junit.Assert;
import org.junit.Test;
import static com.metamx.druid.partition.IntegerPartitionChunk.make;
import static io.druid.timeline.partition.IntegerPartitionChunk.make;
/**
*/

View File

@ -1,6 +1,6 @@
/*
* Druid - a distributed column store.
* Copyright (C) 2012 Metamarkets Group Inc.
* 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
@ -17,12 +17,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.metamx.druid.partition;
package io.druid.timeline.partition;
import org.junit.Assert;
import org.junit.Test;
import static com.metamx.druid.partition.StringPartitionChunk.make;
import static io.druid.timeline.partition.StringPartitionChunk.make;
/**
*/

View File

@ -1,39 +0,0 @@
digraph DruidDataFlow {
graph [bgcolor="#fffef5", clusterrank=global, rankdir=TB];
node [color="#0a0701", fillcolor="#fdf4c6", fontname=Helvetica, shape=box, style=filled, label="\N"];
edge [color="#377d18"];
1 [label = "REST query"];
2 [label = "realtime_data_src"];
4 [label = "indexed segments\nblob_store (S3, HDFS)"];
5 [label = "Realtime.working_set"];
6 [label = "Realtime.spill_disk"];
7 [label = "HDFS_data_src"];
8 [label = "external_data_src"];
9 [label = "Realtime.local_disk"];
10 [label = "metadata_store (mysql)"];
11 [label = "HadoopDruidIndexer.working_set"];
12 [label = "IndexerService.working_set"];
2 -> 5 [label = "Realtime.Firehose"];
5 -> 6 [label = "Realtime.Firehose"];
5 -> 9 [label = "Realtime.Indexer"];
6 -> 9 [label = "Realtime.Indexer"];
5 -> 10 [label = "Realtime.MetadataUpdater"];
7 -> 11 [label = "HadoopDruidIndexer"];
11 -> 4 [label = "HadoopDruidIndexer"];
11 -> 10 [label = "HadoopDruidIndexer"];
8 -> 12 [label = "IndexerService"];
12 -> 4 [label = "IndexerService"];
12 -> 10 [label = "IndexerService"];
9 -> 4 [label = "Realtime.segmentPusher"];
5 -> 1 [label = " results "];
1 -> 5 [label = " query "];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

View File

@ -1,128 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Generated by dot version 1.13 (v16) (Mon August 23, 2004)
For user: (peb) Paul E Baclace Title: DruidDataFlow Pages: 1 -->
<svg width="950pt" height="404pt"
viewBox = "-1 -1 949 403"
xmlns="http://www.w3.org/2000/svg">
<g id="graph0" class="graph" style="font-family:Times-Roman;font-size:14.00;">
<title>DruidDataFlow</title>
<polygon style="fill:#fffef5;stroke:#fffef5;" points="0,401 0,-1 948,-1 948,401 0,401"/>
<g id="node1" class="node"><title>1</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="177,4 91,4 91,40 177,40 177,4"/>
<text text-anchor="middle" x="134" y="27" style="font-family:Helvetica;">REST query</text>
</g>
<g id="node4" class="node"><title>5</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="272,92 124,92 124,128 272,128 272,92"/>
<text text-anchor="middle" x="198" y="115" style="font-family:Helvetica;">Realtime.working_set</text>
</g>
<g id="edge28" class="edge"><title>1-&gt;5</title>
<path style="fill:none;stroke:#377d18;" d="M162,40C169,45 175,51 180,58 185,65 189,74 192,82"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="195,82 194,92 189,83 195,82"/>
<text text-anchor="middle" x="205" y="71"> query </text>
</g>
<g id="node2" class="node"><title>2</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="335,4 209,4 209,40 335,40 335,4"/>
<text text-anchor="middle" x="272" y="27" style="font-family:Helvetica;">realtime_data_src</text>
</g>
<g id="edge2" class="edge"><title>2-&gt;5</title>
<path style="fill:none;stroke:#377d18;" d="M257,40C246,53 232,70 220,84"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="222,87 213,92 217,82 222,87"/>
<text text-anchor="middle" x="293" y="71">Realtime.Firehose</text>
</g>
<g id="node3" class="node"><title>4</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="328,356 172,356 172,396 328,396 328,356"/>
<text text-anchor="middle" x="250" y="373" style="font-family:Helvetica;">indexed segments</text>
<text text-anchor="middle" x="250" y="389" style="font-family:Helvetica;">blob_store (S3, HDFS)</text>
</g>
<g id="edge26" class="edge"><title>5-&gt;1</title>
<path style="fill:none;stroke:#377d18;" d="M150,92C143,87 137,81 133,74 129,67 128,58 128,50"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="125,50 129,40 131,50 125,50"/>
<text text-anchor="middle" x="154" y="71"> results </text>
</g>
<g id="node5" class="node"><title>6</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="136,180 6,180 6,216 136,216 136,180"/>
<text text-anchor="middle" x="71" y="203" style="font-family:Helvetica;">Realtime.spill_disk</text>
</g>
<g id="edge4" class="edge"><title>5-&gt;6</title>
<path style="fill:none;stroke:#377d18;" d="M123,127C105,133 89,139 82,146 76,152 74,161 72,170"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="75,170 71,180 69,170 75,170"/>
<text text-anchor="middle" x="136" y="159">Realtime.Firehose</text>
</g>
<g id="node8" class="node"><title>9</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="143,268 9,268 9,304 143,304 143,268"/>
<text text-anchor="middle" x="76" y="291" style="font-family:Helvetica;">Realtime.local_disk</text>
</g>
<g id="edge6" class="edge"><title>5-&gt;9</title>
<path style="fill:none;stroke:#377d18;" d="M200,128C203,158 204,215 175,250 171,255 162,260 151,264"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="153,267 142,268 150,261 153,267"/>
<text text-anchor="middle" x="247" y="203">Realtime.Indexer</text>
</g>
<g id="node9" class="node"><title>10</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="726,358 564,358 564,394 726,394 726,358"/>
<text text-anchor="middle" x="645" y="381" style="font-family:Helvetica;">metadata_store (mysql)</text>
</g>
<g id="edge10" class="edge"><title>5-&gt;10</title>
<path style="fill:none;stroke:#377d18;" d="M273,115C391,125 611,146 682,180 751,214 798,276 754,338 750,344 739,349 727,354"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="728,358 717,358 725,351 728,358"/>
<text text-anchor="middle" x="835" y="247">Realtime.MetadataUpdater</text>
</g>
<g id="edge8" class="edge"><title>6-&gt;9</title>
<path style="fill:none;stroke:#377d18;" d="M72,216C73,228 74,244 74,258"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="77,258 75,268 71,258 77,258"/>
<text text-anchor="middle" x="123" y="247">Realtime.Indexer</text>
</g>
<g id="node6" class="node"><title>7</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="672,180 558,180 558,216 672,216 672,180"/>
<text text-anchor="middle" x="615" y="203" style="font-family:Helvetica;">HDFS_data_src</text>
</g>
<g id="node10" class="node"><title>11</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="726,268 504,268 504,304 726,304 726,268"/>
<text text-anchor="middle" x="615" y="291" style="font-family:Helvetica;">HadoopDruidIndexer.working_set</text>
</g>
<g id="edge12" class="edge"><title>7-&gt;11</title>
<path style="fill:none;stroke:#377d18;" d="M615,216C615,228 615,244 615,258"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="619,258 615,268 612,258 619,258"/>
<text text-anchor="middle" x="674" y="247">HadoopDruidIndexer</text>
</g>
<g id="node7" class="node"><title>8</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="438,180 312,180 312,216 438,216 438,180"/>
<text text-anchor="middle" x="375" y="203" style="font-family:Helvetica;">external_data_src</text>
</g>
<g id="node11" class="node"><title>12</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="464,268 276,268 276,304 464,304 464,268"/>
<text text-anchor="middle" x="370" y="291" style="font-family:Helvetica;">IndexerService.working_set</text>
</g>
<g id="edge18" class="edge"><title>8-&gt;12</title>
<path style="fill:none;stroke:#377d18;" d="M374,216C373,228 372,244 372,258"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="375,258 371,268 369,258 375,258"/>
<text text-anchor="middle" x="414" y="247">IndexerService</text>
</g>
<g id="edge24" class="edge"><title>9-&gt;4</title>
<path style="fill:none;stroke:#377d18;" d="M85,304C91,316 100,330 112,338 126,348 144,356 161,361"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="162,358 171,364 160,364 162,358"/>
<text text-anchor="middle" x="181" y="335">Realtime.segmentPusher</text>
</g>
<g id="edge14" class="edge"><title>11-&gt;4</title>
<path style="fill:none;stroke:#377d18;" d="M553,304C536,309 519,315 503,322 488,328 486,334 472,338 430,353 380,362 339,368"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="339,371 329,369 339,365 339,371"/>
<text text-anchor="middle" x="568" y="335">HadoopDruidIndexer</text>
</g>
<g id="edge16" class="edge"><title>11-&gt;10</title>
<path style="fill:none;stroke:#377d18;" d="M621,304C625,317 631,334 636,348"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="639,347 639,358 633,349 639,347"/>
<text text-anchor="middle" x="690" y="335">HadoopDruidIndexer</text>
</g>
<g id="edge20" class="edge"><title>12-&gt;4</title>
<path style="fill:none;stroke:#377d18;" d="M300,304C284,310 270,316 264,322 258,328 255,337 253,346"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="256,347 251,356 250,346 256,347"/>
<text text-anchor="middle" x="306" y="335">IndexerService</text>
</g>
<g id="edge22" class="edge"><title>12-&gt;10</title>
<path style="fill:none;stroke:#377d18;" d="M370,304C371,316 374,330 384,338 396,349 483,361 554,368"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="554,365 564,369 554,371 554,365"/>
<text text-anchor="middle" x="426" y="335">IndexerService</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -1,27 +0,0 @@
digraph DruidDataFlow {
graph [bgcolor="#fffef5", clusterrank=global, rankdir=TB];
node [color="#0a0701", fillcolor="#fdf4c6", fontname=Helvetica, shape=box, style=filled, label="\N"];
edge [color="#377d18"];
1 [label = "REST query"];
10 [label = "Broker.query_cache"];
2 [label = "realtime_data_src"];
3 [label = "Compute.disk_cache"];
4 [label = "indexed segments\nblob_store (S3, HDFS)"];
5 [label = "Realtime.working_set"];
6 [label = "Compute.working_set"];
2 -> 5 [label = "Realtime.Firehose"];
5 -> 4 [label = "Realtime.segmentPusher"];
4 -> 3 [label = "Compute.load"];
3 -> 6 [label = "Compute.map"];
5 -> 10 [label = " results "];
6 -> 10 [label = " results "];
10 -> 1 [label = " results "];
10 -> 5 [label = " query "];
10 -> 6 [label = " query "];
1 -> 10 [label = " query "];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

View File

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Generated by dot version 1.13 (v16) (Mon August 23, 2004)
For user: (peb) Paul E Baclace Title: DruidDataFlow Pages: 1 -->
<svg width="405pt" height="492pt"
viewBox = "-1 -1 404 491"
xmlns="http://www.w3.org/2000/svg">
<g id="graph0" class="graph" style="font-family:Times-Roman;font-size:14.00;">
<title>DruidDataFlow</title>
<polygon style="fill:#fffef5;stroke:#fffef5;" points="0,489 0,-1 403,-1 403,489 0,489"/>
<g id="node1" class="node"><title>1</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="163,4 77,4 77,40 163,40 163,4"/>
<text text-anchor="middle" x="120" y="27" style="font-family:Helvetica;">REST query</text>
</g>
<g id="node2" class="node"><title>10</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="189,92 51,92 51,128 189,128 189,92"/>
<text text-anchor="middle" x="120" y="115" style="font-family:Helvetica;">Broker.query_cache</text>
</g>
<g id="edge20" class="edge"><title>1-&gt;10</title>
<path style="fill:none;stroke:#377d18;" d="M94,40C89,45 84,51 81,58 77,67 81,76 87,84"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="90,82 94,92 85,87 90,82"/>
<text text-anchor="middle" x="104" y="71"> query </text>
</g>
<g id="edge14" class="edge"><title>10-&gt;1</title>
<path style="fill:none;stroke:#377d18;" d="M123,92C123,86 124,80 125,74 125,66 125,58 124,50"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="121,50 123,40 127,50 121,50"/>
<text text-anchor="middle" x="146" y="71"> results </text>
</g>
<g id="node6" class="node"><title>5</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="303,180 155,180 155,216 303,216 303,180"/>
<text text-anchor="middle" x="229" y="203" style="font-family:Helvetica;">Realtime.working_set</text>
</g>
<g id="edge16" class="edge"><title>10-&gt;5</title>
<path style="fill:none;stroke:#377d18;" d="M181,128C188,132 195,138 204,146 211,153 215,162 219,171"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="222,169 223,180 216,172 222,169"/>
<text text-anchor="middle" x="232" y="159"> query </text>
</g>
<g id="node7" class="node"><title>6</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="172,448 22,448 22,484 172,484 172,448"/>
<text text-anchor="middle" x="97" y="471" style="font-family:Helvetica;">Compute.working_set</text>
</g>
<g id="edge18" class="edge"><title>10-&gt;6</title>
<path style="fill:none;stroke:#377d18;" d="M78,128C46,144 23,157 23,198 23,198 23,198 23,378 23,404 41,426 60,442"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="62,439 68,448 58,445 62,439"/>
<text text-anchor="middle" x="43" y="293"> query </text>
</g>
<g id="node3" class="node"><title>2</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="359,92 233,92 233,128 359,128 359,92"/>
<text text-anchor="middle" x="296" y="115" style="font-family:Helvetica;">realtime_data_src</text>
</g>
<g id="edge2" class="edge"><title>2-&gt;5</title>
<path style="fill:none;stroke:#377d18;" d="M286,128C280,138 272,151 264,162 261,166 258,169 255,173"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="258,175 248,180 253,170 258,175"/>
<text text-anchor="middle" x="326" y="159">Realtime.Firehose</text>
</g>
<g id="node4" class="node"><title>3</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="280,360 136,360 136,396 280,396 280,360"/>
<text text-anchor="middle" x="208" y="383" style="font-family:Helvetica;">Compute.disk_cache</text>
</g>
<g id="edge8" class="edge"><title>3-&gt;6</title>
<path style="fill:none;stroke:#377d18;" d="M185,396C169,409 146,427 128,442"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="130,445 120,448 126,439 130,445"/>
<text text-anchor="middle" x="200" y="427">Compute.map</text>
</g>
<g id="node5" class="node"><title>4</title>
<polygon style="fill:#fdf4c6;stroke:#0a0701;" points="315,268 159,268 159,308 315,308 315,268"/>
<text text-anchor="middle" x="237" y="285" style="font-family:Helvetica;">indexed segments</text>
<text text-anchor="middle" x="237" y="301" style="font-family:Helvetica;">blob_store (S3, HDFS)</text>
</g>
<g id="edge6" class="edge"><title>4-&gt;3</title>
<path style="fill:none;stroke:#377d18;" d="M230,308C226,321 221,337 217,350"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="220,351 214,360 214,349 220,351"/>
<text text-anchor="middle" x="263" y="339">Compute.load</text>
</g>
<g id="edge10" class="edge"><title>5-&gt;10</title>
<path style="fill:none;stroke:#377d18;" d="M183,180C174,175 165,169 157,162 149,155 141,146 135,137"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="132,138 130,128 138,135 132,138"/>
<text text-anchor="middle" x="178" y="159"> results </text>
</g>
<g id="edge4" class="edge"><title>5-&gt;4</title>
<path style="fill:none;stroke:#377d18;" d="M231,216C232,228 233,244 234,258"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="237,258 235,268 231,258 237,258"/>
<text text-anchor="middle" x="302" y="247">Realtime.segmentPusher</text>
</g>
<g id="edge12" class="edge"><title>6-&gt;10</title>
<path style="fill:none;stroke:#377d18;" d="M97,448C97,430 98,403 97,378 97,198 97,198 97,198 98,177 104,155 110,138"/>
<polygon style="fill:#377d18;stroke:#377d18;" points="107,137 113,128 113,139 107,137"/>
<text text-anchor="middle" x="119" y="293"> results </text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

Some files were not shown because too many files have changed in this diff Show More