diff --git a/.gitignore b/.gitignore
index c7f1290850b..df8a58abf2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ target
*.log
*.DS_Store
_site
+dependency-reduced-pom.xml
diff --git a/.travis.yml b/.travis.yml
index 81f35b2aaa7..e455942a18a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
language: java
-dist: precise
+dist: trusty
jdk:
- oraclejdk8
@@ -19,17 +19,16 @@ matrix:
# processing module test
- sudo: false
- install: mvn install -q -ff -DskipTests -B
- script: mvn test -B -Pparallel-test -Dmaven.fork.count=2 -pl processing
+ install: echo "MAVEN_OPTS='-Xmx3000m'" > ~/.mavenrc && mvn install -q -ff -DskipTests -B
+ script: echo "MAVEN_OPTS='-Xmx512m'" > ~/.mavenrc && mvn test -B -Pparallel-test -Dmaven.fork.count=2 -pl processing
# non-processing modules test
- sudo: false
- install: mvn install -q -ff -DskipTests -B
- script: mvn test -B -Pparallel-test -Dmaven.fork.count=2 -pl '!processing'
+ install: echo "MAVEN_OPTS='-Xmx3000m'" > ~/.mavenrc && mvn install -q -ff -DskipTests -B
+ script: echo "MAVEN_OPTS='-Xmx512m'" > ~/.mavenrc && mvn test -B -Pparallel-test -Dmaven.fork.count=2 -pl '!processing'
# run integration tests
- sudo: required
- dist: trusty
services:
- docker
env:
diff --git a/api/src/main/java/io/druid/data/input/Committer.java b/api/src/main/java/io/druid/data/input/Committer.java
index 04dbe96707e..006bd5a6795 100644
--- a/api/src/main/java/io/druid/data/input/Committer.java
+++ b/api/src/main/java/io/druid/data/input/Committer.java
@@ -18,15 +18,19 @@
*/
package io.druid.data.input;
+
+import io.druid.guice.annotations.ExtensionPoint;
+
/**
* Committer includes a Runnable and a Jackson-serialized metadata object containing the offset
*/
+@ExtensionPoint
public interface Committer extends Runnable
{
- /**
- * @return A json serialized representation of commit metadata,
- * which needs to be serialized and deserialized by Jackson.
- * Commit metadata can be a complex type, but we recommend keeping it to List/Map/"Primitive JSON" types
- * */
- public Object getMetadata();
+ /**
+ * @return A json serialized representation of commit metadata,
+ * which needs to be serialized and deserialized by Jackson.
+ * Commit metadata can be a complex type, but we recommend keeping it to List/Map/"Primitive JSON" types
+ */
+ public Object getMetadata();
}
diff --git a/api/src/main/java/io/druid/data/input/Firehose.java b/api/src/main/java/io/druid/data/input/Firehose.java
index 4f4c640f104..a6f403cf355 100644
--- a/api/src/main/java/io/druid/data/input/Firehose.java
+++ b/api/src/main/java/io/druid/data/input/Firehose.java
@@ -19,6 +19,8 @@
package io.druid.data.input;
+import io.druid.guice.annotations.ExtensionPoint;
+
import javax.annotation.Nullable;
import java.io.Closeable;
@@ -36,6 +38,7 @@ import java.io.Closeable;
* which will be called on another thread, so the operations inside of that callback must be thread-safe.
*
*/
+@ExtensionPoint
public interface Firehose extends Closeable
{
/**
diff --git a/api/src/main/java/io/druid/data/input/FirehoseFactory.java b/api/src/main/java/io/druid/data/input/FirehoseFactory.java
index 2494c13ea71..75049ea8911 100644
--- a/api/src/main/java/io/druid/data/input/FirehoseFactory.java
+++ b/api/src/main/java/io/druid/data/input/FirehoseFactory.java
@@ -22,6 +22,7 @@ package io.druid.data.input;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.druid.data.input.impl.InputRowParser;
import io.druid.data.input.impl.PrefetchableTextFilesFirehoseFactory;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.java.util.common.parsers.ParseException;
import java.io.File;
@@ -32,6 +33,7 @@ import java.io.IOException;
* It currently provides two methods for creating a {@link Firehose} and their default implementations call each other
* for the backward compatibility. Implementations of this interface must implement one of these methods.
*/
+@ExtensionPoint
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface FirehoseFactory
{
diff --git a/api/src/main/java/io/druid/data/input/FirehoseFactoryV2.java b/api/src/main/java/io/druid/data/input/FirehoseFactoryV2.java
index a0fc5e2468f..64a2b11d937 100644
--- a/api/src/main/java/io/druid/data/input/FirehoseFactoryV2.java
+++ b/api/src/main/java/io/druid/data/input/FirehoseFactoryV2.java
@@ -20,8 +20,8 @@
package io.druid.data.input;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
import io.druid.data.input.impl.InputRowParser;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.java.util.common.parsers.ParseException;
import java.io.IOException;
@@ -37,6 +37,7 @@ import java.io.IOException;
* value will throw a surprising NPE. Throwing IOException on connection failure or runtime exception on
* invalid configuration is preferred over returning null.
*/
+@ExtensionPoint
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface FirehoseFactoryV2
{
diff --git a/api/src/main/java/io/druid/data/input/FirehoseV2.java b/api/src/main/java/io/druid/data/input/FirehoseV2.java
index 05f72cc8609..d22f1a59a4f 100644
--- a/api/src/main/java/io/druid/data/input/FirehoseV2.java
+++ b/api/src/main/java/io/druid/data/input/FirehoseV2.java
@@ -19,6 +19,8 @@
package io.druid.data.input;
+import io.druid.guice.annotations.ExtensionPoint;
+
import java.io.Closeable;
/**
* This is an interface that holds onto the stream of incoming data. Realtime data ingestion is built around this
@@ -44,6 +46,7 @@ import java.io.Closeable;
* which will be called on another thread, so the operations inside of that callback must be thread-safe.
*
*/
+@ExtensionPoint
public interface FirehoseV2 extends Closeable
{
/**
diff --git a/api/src/main/java/io/druid/data/input/InputRow.java b/api/src/main/java/io/druid/data/input/InputRow.java
index 40164571bc1..b3f792711f5 100644
--- a/api/src/main/java/io/druid/data/input/InputRow.java
+++ b/api/src/main/java/io/druid/data/input/InputRow.java
@@ -19,6 +19,8 @@
package io.druid.data.input;
+import io.druid.guice.annotations.ExtensionPoint;
+
import java.util.List;
/**
@@ -28,8 +30,8 @@ import java.util.List;
* implement "schema-less" data ingestion that allows the system to add new dimensions as they appear.
*
*/
-public interface
- InputRow extends Row
+@ExtensionPoint
+public interface InputRow extends Row
{
/**
* Returns the dimensions that exist in this row.
diff --git a/api/src/main/java/io/druid/data/input/MapBasedInputRow.java b/api/src/main/java/io/druid/data/input/MapBasedInputRow.java
index 61fe512e2fc..d6f3647ed17 100644
--- a/api/src/main/java/io/druid/data/input/MapBasedInputRow.java
+++ b/api/src/main/java/io/druid/data/input/MapBasedInputRow.java
@@ -19,6 +19,8 @@
package io.druid.data.input;
+import io.druid.guice.annotations.PublicApi;
+import io.druid.java.util.common.DateTimes;
import org.joda.time.DateTime;
import java.util.List;
@@ -26,6 +28,7 @@ import java.util.Map;
/**
*/
+@PublicApi
public class MapBasedInputRow extends MapBasedRow implements InputRow
{
private final List dimensions;
@@ -60,7 +63,7 @@ public class MapBasedInputRow extends MapBasedRow implements InputRow
public String toString()
{
return "MapBasedInputRow{" +
- "timestamp=" + new DateTime(getTimestampFromEpoch()) +
+ "timestamp=" + DateTimes.utc(getTimestampFromEpoch()) +
", event=" + getEvent() +
", dimensions=" + dimensions +
'}';
diff --git a/api/src/main/java/io/druid/data/input/MapBasedRow.java b/api/src/main/java/io/druid/data/input/MapBasedRow.java
index 0d4cbc8be8e..7a8ba07a44a 100644
--- a/api/src/main/java/io/druid/data/input/MapBasedRow.java
+++ b/api/src/main/java/io/druid/data/input/MapBasedRow.java
@@ -22,6 +22,8 @@ package io.druid.data.input;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Lists;
+import io.druid.guice.annotations.PublicApi;
+import io.druid.java.util.common.DateTimes;
import io.druid.java.util.common.parsers.ParseException;
import org.joda.time.DateTime;
@@ -32,6 +34,7 @@ import java.util.regex.Pattern;
/**
*/
+@PublicApi
public class MapBasedRow implements Row
{
private static final Pattern LONG_PAT = Pattern.compile("[-|+]?\\d+");
@@ -54,7 +57,7 @@ public class MapBasedRow implements Row
Map event
)
{
- this(new DateTime(timestamp), event);
+ this(DateTimes.utc(timestamp), event);
}
@Override
diff --git a/api/src/main/java/io/druid/data/input/Row.java b/api/src/main/java/io/druid/data/input/Row.java
index f698c02dd68..f5462ff5bda 100644
--- a/api/src/main/java/io/druid/data/input/Row.java
+++ b/api/src/main/java/io/druid/data/input/Row.java
@@ -21,6 +21,7 @@ package io.druid.data.input;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.druid.guice.annotations.PublicApi;
import org.joda.time.DateTime;
import java.util.List;
@@ -29,6 +30,7 @@ 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.
*/
+@PublicApi
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "version", defaultImpl = MapBasedRow.class)
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = "v1", value = MapBasedRow.class)
diff --git a/api/src/main/java/io/druid/data/input/Rows.java b/api/src/main/java/io/druid/data/input/Rows.java
index 05e1aeec4f9..a31d1b3a224 100644
--- a/api/src/main/java/io/druid/data/input/Rows.java
+++ b/api/src/main/java/io/druid/data/input/Rows.java
@@ -23,33 +23,14 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;
-import io.druid.java.util.common.ISE;
-
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
/**
*/
public class Rows
{
- public static InputRow toCaseInsensitiveInputRow(final Row row, final List dimensions)
- {
- if (row instanceof MapBasedRow) {
- MapBasedRow mapBasedRow = (MapBasedRow) row;
-
- TreeMap caseInsensitiveMap = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
- caseInsensitiveMap.putAll(mapBasedRow.getEvent());
- return new MapBasedInputRow(
- mapBasedRow.getTimestamp(),
- dimensions,
- caseInsensitiveMap
- );
- }
- throw new ISE("Can only convert MapBasedRow objects because we are ghetto like that.");
- }
-
/**
* @param timeStamp rollup up timestamp to be used to create group key
* @param inputRow input row
diff --git a/api/src/main/java/io/druid/data/input/impl/DimensionSchema.java b/api/src/main/java/io/druid/data/input/impl/DimensionSchema.java
index fd9acb62be1..fb61f5b977b 100644
--- a/api/src/main/java/io/druid/data/input/impl/DimensionSchema.java
+++ b/api/src/main/java/io/druid/data/input/impl/DimensionSchema.java
@@ -26,10 +26,12 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonValue;
import com.google.common.base.Preconditions;
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.StringUtils;
/**
*/
+@PublicApi
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = StringDimensionSchema.class)
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = DimensionSchema.STRING_TYPE_NAME, value = StringDimensionSchema.class),
diff --git a/api/src/main/java/io/druid/data/input/impl/DimensionsSpec.java b/api/src/main/java/io/druid/data/input/impl/DimensionsSpec.java
index ecbfb978887..3d48a95abe7 100644
--- a/api/src/main/java/io/druid/data/input/impl/DimensionsSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/DimensionsSpec.java
@@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.parsers.ParserUtils;
import javax.annotation.Nullable;
@@ -37,7 +37,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-
+@PublicApi
public class DimensionsSpec
{
private final List dimensions;
diff --git a/api/src/main/java/io/druid/data/input/impl/InputRowParser.java b/api/src/main/java/io/druid/data/input/impl/InputRowParser.java
index 13c7cc18edf..dcf369ca959 100644
--- a/api/src/main/java/io/druid/data/input/impl/InputRowParser.java
+++ b/api/src/main/java/io/druid/data/input/impl/InputRowParser.java
@@ -22,7 +22,9 @@ package io.druid.data.input.impl;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.druid.data.input.InputRow;
+import io.druid.guice.annotations.ExtensionPoint;
+@ExtensionPoint
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = StringInputRowParser.class)
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = "string", value = StringInputRowParser.class),
diff --git a/api/src/main/java/io/druid/data/input/impl/JSONLowercaseParseSpec.java b/api/src/main/java/io/druid/data/input/impl/JSONLowercaseParseSpec.java
index 17600ee18f4..177a2b39a75 100644
--- a/api/src/main/java/io/druid/data/input/impl/JSONLowercaseParseSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/JSONLowercaseParseSpec.java
@@ -22,7 +22,6 @@ package io.druid.data.input.impl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
-
import io.druid.java.util.common.parsers.JSONToLowerParser;
import io.druid.java.util.common.parsers.Parser;
diff --git a/api/src/main/java/io/druid/data/input/impl/JSONParseSpec.java b/api/src/main/java/io/druid/data/input/impl/JSONParseSpec.java
index 81ce73b94a4..d58dac4aa4a 100644
--- a/api/src/main/java/io/druid/data/input/impl/JSONParseSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/JSONParseSpec.java
@@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.databind.ObjectMapper;
-
import io.druid.java.util.common.parsers.JSONPathParser;
import io.druid.java.util.common.parsers.Parser;
diff --git a/api/src/main/java/io/druid/data/input/impl/JavaScriptParseSpec.java b/api/src/main/java/io/druid/data/input/impl/JavaScriptParseSpec.java
index 620f8109bd1..499f61d5bfe 100644
--- a/api/src/main/java/io/druid/data/input/impl/JavaScriptParseSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/JavaScriptParseSpec.java
@@ -22,7 +22,6 @@ package io.druid.data.input.impl;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-
import io.druid.java.util.common.ISE;
import io.druid.java.util.common.parsers.JavaScriptParser;
import io.druid.java.util.common.parsers.Parser;
diff --git a/api/src/main/java/io/druid/data/input/impl/ParseSpec.java b/api/src/main/java/io/druid/data/input/impl/ParseSpec.java
index 96c06237d9b..7efc397f5f4 100644
--- a/api/src/main/java/io/druid/data/input/impl/ParseSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/ParseSpec.java
@@ -22,13 +22,12 @@ package io.druid.data.input.impl;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.java.util.common.parsers.Parser;
import java.util.List;
-/**
- */
+@ExtensionPoint
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "format", defaultImpl = DelimitedParseSpec.class)
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = "json", value = JSONParseSpec.class),
diff --git a/api/src/main/java/io/druid/data/input/impl/RegexParseSpec.java b/api/src/main/java/io/druid/data/input/impl/RegexParseSpec.java
index a90978bf2b1..926328c701a 100644
--- a/api/src/main/java/io/druid/data/input/impl/RegexParseSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/RegexParseSpec.java
@@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-
import io.druid.java.util.common.parsers.Parser;
import io.druid.java.util.common.parsers.RegexParser;
diff --git a/api/src/main/java/io/druid/data/input/impl/TimestampSpec.java b/api/src/main/java/io/druid/data/input/impl/TimestampSpec.java
index 8f83d25b714..ffb767bd7ac 100644
--- a/api/src/main/java/io/druid/data/input/impl/TimestampSpec.java
+++ b/api/src/main/java/io/druid/data/input/impl/TimestampSpec.java
@@ -22,6 +22,7 @@ package io.druid.data.input.impl;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Function;
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.parsers.TimestampParser;
import org.joda.time.DateTime;
@@ -31,6 +32,7 @@ import java.util.Objects;
/**
*/
+@PublicApi
public class TimestampSpec
{
private static class ParseCtx
diff --git a/api/src/main/java/io/druid/guice/Binders.java b/api/src/main/java/io/druid/guice/Binders.java
index 1d6b220ffa7..30315d6fdeb 100644
--- a/api/src/main/java/io/druid/guice/Binders.java
+++ b/api/src/main/java/io/druid/guice/Binders.java
@@ -22,16 +22,18 @@ package io.druid.guice;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.multibindings.MapBinder;
+import io.druid.guice.annotations.PublicApi;
import io.druid.segment.loading.DataSegmentArchiver;
import io.druid.segment.loading.DataSegmentFinder;
-import io.druid.segment.loading.DataSegmentMover;
import io.druid.segment.loading.DataSegmentKiller;
+import io.druid.segment.loading.DataSegmentMover;
import io.druid.segment.loading.DataSegmentPuller;
import io.druid.segment.loading.DataSegmentPusher;
import io.druid.tasklogs.TaskLogs;
/**
*/
+@PublicApi
public class Binders
{
public static MapBinder dataSegmentPullerBinder(Binder binder)
diff --git a/api/src/main/java/io/druid/guice/ConditionalMultibind.java b/api/src/main/java/io/druid/guice/ConditionalMultibind.java
index 2846977944c..2b9ea4162c4 100644
--- a/api/src/main/java/io/druid/guice/ConditionalMultibind.java
+++ b/api/src/main/java/io/druid/guice/ConditionalMultibind.java
@@ -23,6 +23,7 @@ import com.google.common.base.Predicate;
import com.google.inject.Binder;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
+import io.druid.guice.annotations.PublicApi;
import java.lang.annotation.Annotation;
import java.util.Properties;
@@ -43,6 +44,7 @@ import java.util.Properties;
* At injection time, you will get the items that satisfy their corresponding predicates by calling
* injector.getInstance(Key.get(new TypeLiteral>(){}))
*/
+@PublicApi
public class ConditionalMultibind
{
diff --git a/api/src/main/java/io/druid/guice/DruidGuiceExtensions.java b/api/src/main/java/io/druid/guice/DruidGuiceExtensions.java
index 149f72c9be7..956abc7abcd 100644
--- a/api/src/main/java/io/druid/guice/DruidGuiceExtensions.java
+++ b/api/src/main/java/io/druid/guice/DruidGuiceExtensions.java
@@ -21,9 +21,11 @@ package io.druid.guice;
import com.google.inject.Binder;
import com.google.inject.Module;
+import io.druid.guice.annotations.PublicApi;
/**
*/
+@PublicApi
public class DruidGuiceExtensions implements Module
{
@Override
diff --git a/api/src/main/java/io/druid/guice/DruidScopes.java b/api/src/main/java/io/druid/guice/DruidScopes.java
index a837928a2a7..d7aeab313c2 100644
--- a/api/src/main/java/io/druid/guice/DruidScopes.java
+++ b/api/src/main/java/io/druid/guice/DruidScopes.java
@@ -23,9 +23,11 @@ import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
import com.google.inject.Scopes;
+import io.druid.guice.annotations.PublicApi;
/**
*/
+@PublicApi
public class DruidScopes
{
public static final Scope SINGLETON = new Scope()
diff --git a/api/src/main/java/io/druid/guice/Jerseys.java b/api/src/main/java/io/druid/guice/Jerseys.java
index 9c0163a4fb5..51520eae749 100644
--- a/api/src/main/java/io/druid/guice/Jerseys.java
+++ b/api/src/main/java/io/druid/guice/Jerseys.java
@@ -23,9 +23,11 @@ import com.google.inject.Binder;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import io.druid.guice.annotations.JSR311Resource;
+import io.druid.guice.annotations.PublicApi;
/**
*/
+@PublicApi
public class Jerseys
{
public static void addResource(Binder binder, Class> resourceClazz)
diff --git a/api/src/main/java/io/druid/guice/JsonConfigProvider.java b/api/src/main/java/io/druid/guice/JsonConfigProvider.java
index 4e9b5f64f98..c3a9cfd64d8 100644
--- a/api/src/main/java/io/druid/guice/JsonConfigProvider.java
+++ b/api/src/main/java/io/druid/guice/JsonConfigProvider.java
@@ -26,6 +26,7 @@ import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.util.Types;
+import io.druid.guice.annotations.PublicApi;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
@@ -76,6 +77,7 @@ import java.util.Properties;
*
* @param type of config object to provide.
*/
+@PublicApi
public class JsonConfigProvider implements Provider>
{
@SuppressWarnings("unchecked")
diff --git a/api/src/main/java/io/druid/guice/LazySingleton.java b/api/src/main/java/io/druid/guice/LazySingleton.java
index 452621df812..5acf6466be6 100644
--- a/api/src/main/java/io/druid/guice/LazySingleton.java
+++ b/api/src/main/java/io/druid/guice/LazySingleton.java
@@ -20,6 +20,7 @@
package io.druid.guice;
import com.google.inject.ScopeAnnotation;
+import io.druid.guice.annotations.PublicApi;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -31,6 +32,7 @@ import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ScopeAnnotation
+@PublicApi
public @interface LazySingleton
{
}
diff --git a/api/src/main/java/io/druid/guice/LifecycleModule.java b/api/src/main/java/io/druid/guice/LifecycleModule.java
index 2d9968cdc3c..2dc340dd84e 100644
--- a/api/src/main/java/io/druid/guice/LifecycleModule.java
+++ b/api/src/main/java/io/druid/guice/LifecycleModule.java
@@ -27,7 +27,6 @@ import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.name.Names;
-
import io.druid.java.util.common.lifecycle.Lifecycle;
import java.lang.annotation.Annotation;
diff --git a/api/src/main/java/io/druid/guice/LifecycleScope.java b/api/src/main/java/io/druid/guice/LifecycleScope.java
index 42a34979a3d..19914b0f0f3 100644
--- a/api/src/main/java/io/druid/guice/LifecycleScope.java
+++ b/api/src/main/java/io/druid/guice/LifecycleScope.java
@@ -23,7 +23,6 @@ import com.google.common.collect.Lists;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
-
import io.druid.java.util.common.lifecycle.Lifecycle;
import io.druid.java.util.common.logger.Logger;
diff --git a/api/src/main/java/io/druid/guice/ManageLifecycle.java b/api/src/main/java/io/druid/guice/ManageLifecycle.java
index e062aa3994b..53d4d8f33e9 100644
--- a/api/src/main/java/io/druid/guice/ManageLifecycle.java
+++ b/api/src/main/java/io/druid/guice/ManageLifecycle.java
@@ -20,6 +20,7 @@
package io.druid.guice;
import com.google.inject.ScopeAnnotation;
+import io.druid.guice.annotations.PublicApi;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -34,6 +35,7 @@ import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ScopeAnnotation
+@PublicApi
public @interface ManageLifecycle
{
}
diff --git a/api/src/main/java/io/druid/guice/ManageLifecycleLast.java b/api/src/main/java/io/druid/guice/ManageLifecycleLast.java
index ff88784898a..02a7ff15d98 100644
--- a/api/src/main/java/io/druid/guice/ManageLifecycleLast.java
+++ b/api/src/main/java/io/druid/guice/ManageLifecycleLast.java
@@ -20,6 +20,7 @@
package io.druid.guice;
import com.google.inject.ScopeAnnotation;
+import io.druid.guice.annotations.PublicApi;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -34,6 +35,7 @@ import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ScopeAnnotation
+@PublicApi
public @interface ManageLifecycleLast
{
}
diff --git a/api/src/main/java/io/druid/guice/PolyBind.java b/api/src/main/java/io/druid/guice/PolyBind.java
index fddeb98c309..fbcdaaaa4ad 100644
--- a/api/src/main/java/io/druid/guice/PolyBind.java
+++ b/api/src/main/java/io/druid/guice/PolyBind.java
@@ -30,6 +30,7 @@ import com.google.inject.TypeLiteral;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.util.Types;
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.StringUtils;
import javax.annotation.Nullable;
@@ -45,6 +46,7 @@ import java.util.Properties;
* 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.
*/
+@PublicApi
public class PolyBind
{
/**
diff --git a/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java
new file mode 100644
index 00000000000..9dc02e17044
--- /dev/null
+++ b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to Metamarkets Group Inc. (Metamarkets) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Metamarkets licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.druid.guice.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Signifies that the annotated type is an extension point. Extension points are interfaces or non-final classes that
+ * may be subclassed in extensions in order to add functionality to Druid. Extension points may change in breaking ways
+ * only between major Druid release lines (e.g. 0.10.x -> 0.11.0), but otherwise must remain stable. Extension points
+ * may change at any time in non-breaking ways, however, such as by adding new default methods to an interface.
+ *
+ * All public and protected fields, methods, and constructors of annotated classes and interfaces are considered
+ * stable in this sense. If a class is not annotated, but an individual field, method, or constructor is
+ * annotated, then only that particular field, method, or constructor is considered an extension API.
+ *
+ * Extension points are all considered public APIs in the sense of {@link PublicApi}, even if not explicitly annotated
+ * as such.
+ *
+ * Note that there are number of injectable interfaces that are not annotated with {@code ExtensionPoint}. You may
+ * still extend these interfaces in extensions, but your extension may need to be recompiled even for a minor
+ * update of Druid.
+ *
+ * @see PublicApi
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.SOURCE)
+public @interface ExtensionPoint
+{
+}
diff --git a/api/src/main/java/io/druid/guice/annotations/Global.java b/api/src/main/java/io/druid/guice/annotations/Global.java
index 25222ce4bf3..84de2013261 100644
--- a/api/src/main/java/io/druid/guice/annotations/Global.java
+++ b/api/src/main/java/io/druid/guice/annotations/Global.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
@BindingAnnotation
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
+@PublicApi
public @interface Global
{
}
diff --git a/api/src/main/java/io/druid/guice/annotations/JSR311Resource.java b/api/src/main/java/io/druid/guice/annotations/JSR311Resource.java
index 465840cc7d0..948bd576063 100644
--- a/api/src/main/java/io/druid/guice/annotations/JSR311Resource.java
+++ b/api/src/main/java/io/druid/guice/annotations/JSR311Resource.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
@BindingAnnotation
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
+@PublicApi
public @interface JSR311Resource
{
}
diff --git a/api/src/main/java/io/druid/guice/annotations/Json.java b/api/src/main/java/io/druid/guice/annotations/Json.java
index 73dac864e9a..4371554977a 100644
--- a/api/src/main/java/io/druid/guice/annotations/Json.java
+++ b/api/src/main/java/io/druid/guice/annotations/Json.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
+@PublicApi
public @interface Json
{
}
diff --git a/api/src/main/java/io/druid/guice/annotations/PublicApi.java b/api/src/main/java/io/druid/guice/annotations/PublicApi.java
new file mode 100644
index 00000000000..f398dfe81a2
--- /dev/null
+++ b/api/src/main/java/io/druid/guice/annotations/PublicApi.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to Metamarkets Group Inc. (Metamarkets) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Metamarkets licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.druid.guice.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Signifies that the annotated entity is a public API for extension authors. Public APIs may change in breaking ways
+ * only between major Druid release lines (e.g. 0.10.x -> 0.11.0), but otherwise must remain stable. Public APIs may
+ * change at any time in non-breaking ways, however, such as by adding new fields, methods, or constructors.
+ *
+ * Note that interfaces annotated with {@code PublicApi} but not with {@link ExtensionPoint} are not meant to be
+ * subclassed in extensions. In this case, the annotation simply signifies that the interface is stable for callers.
+ * In particular, since it is not meant to be subclassed, new non-default methods may be added to an interface and
+ * new abstract methods may be added to a class.
+ *
+ * If a class or interface is annotated, then all public and protected fields, methods, and constructors that class
+ * or interface are considered stable in this sense. If a class is not annotated, but an individual field, method, or
+ * constructor is annotated, then only that particular field, method, or constructor is considered a public API.
+ *
+ * Classes, fields, method, and constructors _not_ annotated with {@code @PublicApi} may be modified or removed
+ * in any Druid release, unless they are annotated with {@link ExtensionPoint} (which implies they are a public API
+ * as well).
+ *
+ * @see ExtensionPoint
+ */
+@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
+@Retention(RetentionPolicy.SOURCE)
+public @interface PublicApi
+{
+}
diff --git a/api/src/main/java/io/druid/guice/annotations/Self.java b/api/src/main/java/io/druid/guice/annotations/Self.java
index e6123fbe188..f5a8b348c4e 100644
--- a/api/src/main/java/io/druid/guice/annotations/Self.java
+++ b/api/src/main/java/io/druid/guice/annotations/Self.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
+@PublicApi
public @interface Self
{
}
diff --git a/api/src/main/java/io/druid/guice/annotations/Smile.java b/api/src/main/java/io/druid/guice/annotations/Smile.java
index 136885a4f46..babfb5a68d7 100644
--- a/api/src/main/java/io/druid/guice/annotations/Smile.java
+++ b/api/src/main/java/io/druid/guice/annotations/Smile.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
+@PublicApi
public @interface Smile
{
}
diff --git a/api/src/main/java/io/druid/initialization/DruidModule.java b/api/src/main/java/io/druid/initialization/DruidModule.java
index 9015dca45be..89bb3d85768 100644
--- a/api/src/main/java/io/druid/initialization/DruidModule.java
+++ b/api/src/main/java/io/druid/initialization/DruidModule.java
@@ -20,11 +20,13 @@
package io.druid.initialization;
import com.fasterxml.jackson.databind.Module;
+import io.druid.guice.annotations.ExtensionPoint;
import java.util.List;
/**
*/
+@ExtensionPoint
public interface DruidModule extends com.google.inject.Module
{
public List extends Module> getJacksonModules();
diff --git a/api/src/main/java/io/druid/js/JavaScriptConfig.java b/api/src/main/java/io/druid/js/JavaScriptConfig.java
index 6b62431aa88..7dc6bb1b2fb 100644
--- a/api/src/main/java/io/druid/js/JavaScriptConfig.java
+++ b/api/src/main/java/io/druid/js/JavaScriptConfig.java
@@ -21,7 +21,13 @@ package io.druid.js;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
+import io.druid.guice.annotations.PublicApi;
+/**
+ * Should be used by extension filters, aggregators, etc, that use JavaScript to determine if JavaScript is enabled
+ * or not.
+ */
+@PublicApi
public class JavaScriptConfig
{
public static final int DEFAULT_OPTIMIZATION_LEVEL = 9;
diff --git a/api/src/main/java/io/druid/segment/SegmentUtils.java b/api/src/main/java/io/druid/segment/SegmentUtils.java
index f1b495f9a13..448eaf0c503 100644
--- a/api/src/main/java/io/druid/segment/SegmentUtils.java
+++ b/api/src/main/java/io/druid/segment/SegmentUtils.java
@@ -21,6 +21,7 @@ package io.druid.segment;
import com.google.common.io.Files;
import com.google.common.primitives.Ints;
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.IOE;
import java.io.File;
@@ -29,7 +30,9 @@ import java.io.IOException;
import java.io.InputStream;
/**
+ * Utility methods useful for implementing deep storage extensions.
*/
+@PublicApi
public class SegmentUtils
{
public static int getVersionFromDir(File inDir) throws IOException
diff --git a/api/src/main/java/io/druid/segment/loading/DataSegmentArchiver.java b/api/src/main/java/io/druid/segment/loading/DataSegmentArchiver.java
index b08365cce9e..2776bfb4aa4 100644
--- a/api/src/main/java/io/druid/segment/loading/DataSegmentArchiver.java
+++ b/api/src/main/java/io/druid/segment/loading/DataSegmentArchiver.java
@@ -19,10 +19,12 @@
package io.druid.segment.loading;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.timeline.DataSegment;
import javax.annotation.Nullable;
+@ExtensionPoint
public interface DataSegmentArchiver
{
/**
diff --git a/api/src/main/java/io/druid/segment/loading/DataSegmentFinder.java b/api/src/main/java/io/druid/segment/loading/DataSegmentFinder.java
index ef4dafbdba9..937a42e72c2 100644
--- a/api/src/main/java/io/druid/segment/loading/DataSegmentFinder.java
+++ b/api/src/main/java/io/druid/segment/loading/DataSegmentFinder.java
@@ -19,6 +19,7 @@
package io.druid.segment.loading;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.timeline.DataSegment;
import java.util.Set;
@@ -27,6 +28,7 @@ import java.util.Set;
* A DataSegmentFinder is responsible for finding Druid segments underneath a specified directory and optionally updates
* all descriptor.json files on deep storage with correct loadSpec.
*/
+@ExtensionPoint
public interface DataSegmentFinder
{
/**
diff --git a/api/src/main/java/io/druid/segment/loading/DataSegmentKiller.java b/api/src/main/java/io/druid/segment/loading/DataSegmentKiller.java
index ba9b879587a..c26a73daeb1 100644
--- a/api/src/main/java/io/druid/segment/loading/DataSegmentKiller.java
+++ b/api/src/main/java/io/druid/segment/loading/DataSegmentKiller.java
@@ -19,12 +19,14 @@
package io.druid.segment.loading;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.timeline.DataSegment;
import java.io.IOException;
/**
*/
+@ExtensionPoint
public interface DataSegmentKiller
{
void kill(DataSegment segments) throws SegmentLoadingException;
diff --git a/api/src/main/java/io/druid/segment/loading/DataSegmentMover.java b/api/src/main/java/io/druid/segment/loading/DataSegmentMover.java
index 81080585cdf..6b59c87e421 100644
--- a/api/src/main/java/io/druid/segment/loading/DataSegmentMover.java
+++ b/api/src/main/java/io/druid/segment/loading/DataSegmentMover.java
@@ -19,10 +19,12 @@
package io.druid.segment.loading;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.timeline.DataSegment;
import java.util.Map;
+@ExtensionPoint
public interface DataSegmentMover
{
public DataSegment move(DataSegment segment, Map targetLoadSpec) throws SegmentLoadingException;
diff --git a/api/src/main/java/io/druid/segment/loading/DataSegmentPuller.java b/api/src/main/java/io/druid/segment/loading/DataSegmentPuller.java
index 46f051138a5..fe2d089b0ec 100644
--- a/api/src/main/java/io/druid/segment/loading/DataSegmentPuller.java
+++ b/api/src/main/java/io/druid/segment/loading/DataSegmentPuller.java
@@ -19,6 +19,7 @@
package io.druid.segment.loading;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.timeline.DataSegment;
import java.io.File;
@@ -26,6 +27,7 @@ import java.io.File;
/**
* A DataSegmentPuller is responsible for pulling data for a particular segment into a particular directory
*/
+@ExtensionPoint
public interface DataSegmentPuller
{
/**
diff --git a/api/src/main/java/io/druid/segment/loading/DataSegmentPusher.java b/api/src/main/java/io/druid/segment/loading/DataSegmentPusher.java
index 3076b5e7c1a..b9bf810f72c 100644
--- a/api/src/main/java/io/druid/segment/loading/DataSegmentPusher.java
+++ b/api/src/main/java/io/druid/segment/loading/DataSegmentPusher.java
@@ -20,6 +20,7 @@
package io.druid.segment.loading;
import com.google.common.base.Joiner;
+import io.druid.guice.annotations.ExtensionPoint;
import io.druid.java.util.common.StringUtils;
import io.druid.timeline.DataSegment;
@@ -30,6 +31,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
+@ExtensionPoint
public interface DataSegmentPusher
{
Joiner JOINER = Joiner.on("/").skipNulls();
diff --git a/api/src/main/java/io/druid/segment/loading/LoadSpec.java b/api/src/main/java/io/druid/segment/loading/LoadSpec.java
index d1945e16085..e026ded7090 100644
--- a/api/src/main/java/io/druid/segment/loading/LoadSpec.java
+++ b/api/src/main/java/io/druid/segment/loading/LoadSpec.java
@@ -20,12 +20,14 @@
package io.druid.segment.loading;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.druid.guice.annotations.ExtensionPoint;
import java.io.File;
/**
* A means of pulling segment files into a destination directory
*/
+@ExtensionPoint
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface LoadSpec
{
diff --git a/api/src/main/java/io/druid/segment/loading/SegmentLoadingException.java b/api/src/main/java/io/druid/segment/loading/SegmentLoadingException.java
index 2ac69944a74..3bd388dc9f9 100644
--- a/api/src/main/java/io/druid/segment/loading/SegmentLoadingException.java
+++ b/api/src/main/java/io/druid/segment/loading/SegmentLoadingException.java
@@ -19,10 +19,12 @@
package io.druid.segment.loading;
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.StringUtils;
/**
*/
+@PublicApi
public class SegmentLoadingException extends Exception
{
public SegmentLoadingException(
diff --git a/api/src/main/java/io/druid/segment/loading/URIDataPuller.java b/api/src/main/java/io/druid/segment/loading/URIDataPuller.java
index 9ae45a3ac42..1a5718fc54b 100644
--- a/api/src/main/java/io/druid/segment/loading/URIDataPuller.java
+++ b/api/src/main/java/io/druid/segment/loading/URIDataPuller.java
@@ -20,6 +20,7 @@
package io.druid.segment.loading;
import com.google.common.base.Predicate;
+import io.druid.guice.annotations.ExtensionPoint;
import java.io.IOException;
import java.io.InputStream;
@@ -28,6 +29,7 @@ import java.net.URI;
/**
* A URIDataPuller has handlings for URI based data
*/
+@ExtensionPoint
public interface URIDataPuller
{
/**
diff --git a/api/src/main/java/io/druid/tasklogs/NoopTaskLogs.java b/api/src/main/java/io/druid/tasklogs/NoopTaskLogs.java
index 4ba760a79b8..3c413303c70 100644
--- a/api/src/main/java/io/druid/tasklogs/NoopTaskLogs.java
+++ b/api/src/main/java/io/druid/tasklogs/NoopTaskLogs.java
@@ -21,7 +21,6 @@ package io.druid.tasklogs;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
-
import io.druid.java.util.common.logger.Logger;
import java.io.File;
diff --git a/api/src/main/java/io/druid/tasklogs/TaskLogKiller.java b/api/src/main/java/io/druid/tasklogs/TaskLogKiller.java
index f03e46ad0c4..7a63f640a8f 100644
--- a/api/src/main/java/io/druid/tasklogs/TaskLogKiller.java
+++ b/api/src/main/java/io/druid/tasklogs/TaskLogKiller.java
@@ -19,10 +19,13 @@
package io.druid.tasklogs;
+import io.druid.guice.annotations.ExtensionPoint;
+
import java.io.IOException;
/**
*/
+@ExtensionPoint
public interface TaskLogKiller
{
void killAll() throws IOException;
diff --git a/api/src/main/java/io/druid/tasklogs/TaskLogPusher.java b/api/src/main/java/io/druid/tasklogs/TaskLogPusher.java
index 3fc16d46f98..9b30e4f2be9 100644
--- a/api/src/main/java/io/druid/tasklogs/TaskLogPusher.java
+++ b/api/src/main/java/io/druid/tasklogs/TaskLogPusher.java
@@ -19,12 +19,15 @@
package io.druid.tasklogs;
+import io.druid.guice.annotations.ExtensionPoint;
+
import java.io.File;
import java.io.IOException;
/**
* Something that knows how to persist local task logs to some form of long-term storage.
*/
+@ExtensionPoint
public interface TaskLogPusher
{
public void pushTaskLog(String taskid, File logFile) throws IOException;
diff --git a/api/src/main/java/io/druid/tasklogs/TaskLogStreamer.java b/api/src/main/java/io/druid/tasklogs/TaskLogStreamer.java
index ccd9a99cdcb..0e60ffcf7c7 100644
--- a/api/src/main/java/io/druid/tasklogs/TaskLogStreamer.java
+++ b/api/src/main/java/io/druid/tasklogs/TaskLogStreamer.java
@@ -21,12 +21,14 @@ package io.druid.tasklogs;
import com.google.common.base.Optional;
import com.google.common.io.ByteSource;
+import io.druid.guice.annotations.ExtensionPoint;
import java.io.IOException;
/**
* Something that knows how to stream logs for tasks.
*/
+@ExtensionPoint
public interface TaskLogStreamer
{
/**
diff --git a/api/src/main/java/io/druid/tasklogs/TaskLogs.java b/api/src/main/java/io/druid/tasklogs/TaskLogs.java
index db76b924e9e..383c3559ae1 100644
--- a/api/src/main/java/io/druid/tasklogs/TaskLogs.java
+++ b/api/src/main/java/io/druid/tasklogs/TaskLogs.java
@@ -19,6 +19,9 @@
package io.druid.tasklogs;
+import io.druid.guice.annotations.ExtensionPoint;
+
+@ExtensionPoint
public interface TaskLogs extends TaskLogStreamer, TaskLogPusher, TaskLogKiller
{
}
diff --git a/api/src/main/java/io/druid/timeline/DataSegment.java b/api/src/main/java/io/druid/timeline/DataSegment.java
index 74322c8c3c6..0b4b2f9fe5c 100644
--- a/api/src/main/java/io/druid/timeline/DataSegment.java
+++ b/api/src/main/java/io/druid/timeline/DataSegment.java
@@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.google.common.collect.Iterables;
+import io.druid.guice.annotations.PublicApi;
import io.druid.jackson.CommaListJoinDeserializer;
import io.druid.jackson.CommaListJoinSerializer;
import io.druid.java.util.common.granularity.Granularities;
@@ -46,6 +47,7 @@ import java.util.Map;
/**
*/
+@PublicApi
public class DataSegment implements Comparable
{
public static String delimiter = "_";
diff --git a/api/src/main/java/io/druid/timeline/DataSegmentUtils.java b/api/src/main/java/io/druid/timeline/DataSegmentUtils.java
index 4d8690e9576..349bbceda03 100644
--- a/api/src/main/java/io/druid/timeline/DataSegmentUtils.java
+++ b/api/src/main/java/io/druid/timeline/DataSegmentUtils.java
@@ -20,6 +20,7 @@
package io.druid.timeline;
import com.google.common.base.Function;
+import io.druid.guice.annotations.PublicApi;
import io.druid.java.util.common.IAE;
import io.druid.java.util.common.StringUtils;
import io.druid.java.util.common.logger.Logger;
@@ -33,6 +34,7 @@ import java.util.Objects;
/**
* identifier to DataSegment.
*/
+@PublicApi
public class DataSegmentUtils
{
private static final Logger LOGGER = new Logger(DataSegmentUtils.class);
@@ -91,7 +93,7 @@ public class DataSegmentUtils
return new SegmentIdentifierParts(
dataSource,
- new Interval(start.getMillis(), end.getMillis()),
+ new Interval(start, end),
version,
trail
);
diff --git a/api/src/main/java/io/druid/timeline/partition/ShardSpec.java b/api/src/main/java/io/druid/timeline/partition/ShardSpec.java
index b76a01941cf..466c9b14582 100644
--- a/api/src/main/java/io/druid/timeline/partition/ShardSpec.java
+++ b/api/src/main/java/io/druid/timeline/partition/ShardSpec.java
@@ -28,7 +28,8 @@ import java.util.List;
import java.util.Map;
/**
- * A Marker interface that exists to combine ShardSpec objects together for Jackson
+ * A Marker interface that exists to combine ShardSpec objects together for Jackson. Note that this is not an
+ * extension API. Extensions are not expected to create new kinds of ShardSpecs.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
diff --git a/api/src/main/java/io/druid/utils/CompressionUtils.java b/api/src/main/java/io/druid/utils/CompressionUtils.java
index 3d628dce1cf..6a551e319e0 100644
--- a/api/src/main/java/io/druid/utils/CompressionUtils.java
+++ b/api/src/main/java/io/druid/utils/CompressionUtils.java
@@ -20,15 +20,17 @@
package io.druid.utils;
+import io.druid.guice.annotations.PublicApi;
+import io.druid.java.util.common.logger.Logger;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import io.druid.java.util.common.logger.Logger;
-
/**
*/
+@PublicApi
public class CompressionUtils
{
private static final Logger log = new Logger(CompressionUtils.class);
diff --git a/api/src/main/java/io/druid/utils/Runnables.java b/api/src/main/java/io/druid/utils/Runnables.java
index d6cec40db15..883aae65b8c 100644
--- a/api/src/main/java/io/druid/utils/Runnables.java
+++ b/api/src/main/java/io/druid/utils/Runnables.java
@@ -19,8 +19,11 @@
package io.druid.utils;
+import io.druid.guice.annotations.PublicApi;
+
/**
*/
+@PublicApi
public class Runnables
{
public static Runnable getNoopRunnable()
diff --git a/api/src/test/java/io/druid/TestObjectMapper.java b/api/src/test/java/io/druid/TestObjectMapper.java
index 740176fb0c5..8ce6fedf843 100644
--- a/api/src/test/java/io/druid/TestObjectMapper.java
+++ b/api/src/test/java/io/druid/TestObjectMapper.java
@@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.druid.java.util.common.Intervals;
import org.joda.time.Interval;
import java.io.IOException;
@@ -61,7 +62,7 @@ public class TestObjectMapper extends ObjectMapper
JsonParser jsonParser, DeserializationContext deserializationContext
) throws IOException, JsonProcessingException
{
- return new Interval(jsonParser.getText());
+ return Intervals.of(jsonParser.getText());
}
}
);
diff --git a/api/src/test/java/io/druid/data/input/MapBasedRowTest.java b/api/src/test/java/io/druid/data/input/MapBasedRowTest.java
index 8d98e11ddcf..05241f50e05 100644
--- a/api/src/test/java/io/druid/data/input/MapBasedRowTest.java
+++ b/api/src/test/java/io/druid/data/input/MapBasedRowTest.java
@@ -19,19 +19,18 @@
package io.druid.data.input;
-import org.joda.time.DateTime;
+import com.google.common.collect.ImmutableMap;
+import io.druid.java.util.common.DateTimes;
import org.junit.Assert;
import org.junit.Test;
-import com.google.common.collect.ImmutableMap;
-
public class MapBasedRowTest
{
@Test
public void testGetLongMetricFromString()
{
MapBasedRow row = new MapBasedRow(
- new DateTime(),
+ DateTimes.nowUtc(),
ImmutableMap.builder()
.put("k0", "-1.2")
.put("k1", "1.23")
diff --git a/api/src/test/java/io/druid/data/input/impl/InputRowParserSerdeTest.java b/api/src/test/java/io/druid/data/input/impl/InputRowParserSerdeTest.java
index 13164db3f9a..144c14418d7 100644
--- a/api/src/test/java/io/druid/data/input/impl/InputRowParserSerdeTest.java
+++ b/api/src/test/java/io/druid/data/input/impl/InputRowParserSerdeTest.java
@@ -27,8 +27,8 @@ import com.google.common.collect.Lists;
import io.druid.TestObjectMapper;
import io.druid.data.input.ByteBufferInputRowParser;
import io.druid.data.input.InputRow;
+import io.druid.java.util.common.DateTimes;
import io.druid.java.util.common.StringUtils;
-import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Test;
@@ -63,7 +63,7 @@ public class InputRowParserSerdeTest
Assert.assertEquals(ImmutableList.of("foo", "bar"), parsed.getDimensions());
Assert.assertEquals(ImmutableList.of("x"), parsed.getDimension("foo"));
Assert.assertEquals(ImmutableList.of("y"), parsed.getDimension("bar"));
- Assert.assertEquals(new DateTime("2000").getMillis(), parsed.getTimestampFromEpoch());
+ Assert.assertEquals(DateTimes.of("2000").getMillis(), parsed.getTimestampFromEpoch());
}
@Test
@@ -79,7 +79,7 @@ public class InputRowParserSerdeTest
Assert.assertEquals(ImmutableList.of("foo", "bar"), parsed.getDimensions());
Assert.assertEquals(ImmutableList.of("x"), parsed.getDimension("foo"));
Assert.assertEquals(ImmutableList.of("y"), parsed.getDimension("bar"));
- Assert.assertEquals(new DateTime("3000").getMillis(), parsed.getTimestampFromEpoch());
+ Assert.assertEquals(DateTimes.of("3000").getMillis(), parsed.getTimestampFromEpoch());
}
}
@@ -219,7 +219,7 @@ public class InputRowParserSerdeTest
Assert.assertEquals(ImmutableList.of("asdf"), parsed.getDimension("hey0barx"));
Assert.assertEquals(ImmutableList.of("456"), parsed.getDimension("metA"));
Assert.assertEquals(ImmutableList.of("5"), parsed.getDimension("newmet"));
- Assert.assertEquals(new DateTime("2999").getMillis(), parsed.getTimestampFromEpoch());
+ Assert.assertEquals(DateTimes.of("2999").getMillis(), parsed.getTimestampFromEpoch());
String testSpec = "{\"enabled\": true,\"useFieldDiscovery\": true, \"fields\": [\"parseThisRootField\"]}";
final JSONPathSpec parsedSpec = jsonMapper.readValue(testSpec, JSONPathSpec.class);
diff --git a/api/src/test/java/io/druid/data/input/impl/JSONLowercaseParseSpecTest.java b/api/src/test/java/io/druid/data/input/impl/JSONLowercaseParseSpecTest.java
index b2e6f4681ad..d8fc9fde77e 100644
--- a/api/src/test/java/io/druid/data/input/impl/JSONLowercaseParseSpecTest.java
+++ b/api/src/test/java/io/druid/data/input/impl/JSONLowercaseParseSpecTest.java
@@ -20,7 +20,6 @@
package io.druid.data.input.impl;
import com.google.common.collect.Lists;
-
import io.druid.java.util.common.parsers.Parser;
import junit.framework.Assert;
import org.junit.Test;
diff --git a/api/src/test/java/io/druid/data/input/impl/ParseSpecTest.java b/api/src/test/java/io/druid/data/input/impl/ParseSpecTest.java
index a1e95c028ad..daf58c648af 100644
--- a/api/src/test/java/io/druid/data/input/impl/ParseSpecTest.java
+++ b/api/src/test/java/io/druid/data/input/impl/ParseSpecTest.java
@@ -20,9 +20,7 @@
package io.druid.data.input.impl;
import com.google.common.collect.Lists;
-
import io.druid.java.util.common.parsers.ParseException;
-
import org.junit.Test;
import java.util.Arrays;
diff --git a/api/src/test/java/io/druid/data/input/impl/PrefetchableTextFilesFirehoseFactoryTest.java b/api/src/test/java/io/druid/data/input/impl/PrefetchableTextFilesFirehoseFactoryTest.java
index 1af0ff4968c..d41164effc1 100644
--- a/api/src/test/java/io/druid/data/input/impl/PrefetchableTextFilesFirehoseFactoryTest.java
+++ b/api/src/test/java/io/druid/data/input/impl/PrefetchableTextFilesFirehoseFactoryTest.java
@@ -24,10 +24,10 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import io.druid.data.input.Firehose;
import io.druid.data.input.Row;
+import io.druid.java.util.common.DateTimes;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.hamcrest.CoreMatchers;
-import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -124,7 +124,7 @@ public class PrefetchableTextFilesFirehoseFactoryTest
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 100; j++) {
final Row row = rows.get(i * 100 + j);
- Assert.assertEquals(new DateTime(20171220 + i), row.getTimestamp());
+ Assert.assertEquals(DateTimes.utc(20171220 + i), row.getTimestamp());
Assert.assertEquals(String.valueOf(i), row.getDimension("a").get(0));
Assert.assertEquals(String.valueOf(j), row.getDimension("b").get(0));
}
diff --git a/api/src/test/java/io/druid/data/input/impl/TimestampSpecTest.java b/api/src/test/java/io/druid/data/input/impl/TimestampSpecTest.java
index 0357ae9ada1..52667a098b5 100644
--- a/api/src/test/java/io/druid/data/input/impl/TimestampSpecTest.java
+++ b/api/src/test/java/io/druid/data/input/impl/TimestampSpecTest.java
@@ -20,6 +20,7 @@
package io.druid.data.input.impl;
import com.google.common.collect.ImmutableMap;
+import io.druid.java.util.common.DateTimes;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.Assert;
@@ -32,7 +33,7 @@ public class TimestampSpecTest
{
TimestampSpec spec = new TimestampSpec("TIMEstamp", "yyyy-MM-dd", null);
Assert.assertEquals(
- new DateTime("2014-03-01"),
+ DateTimes.of("2014-03-01"),
spec.extractTimestamp(ImmutableMap.of("TIMEstamp", "2014-03-01"))
);
}
@@ -40,9 +41,9 @@ public class TimestampSpecTest
@Test
public void testExtractTimestampWithMissingTimestampColumn() throws Exception
{
- TimestampSpec spec = new TimestampSpec(null, null, new DateTime(0));
+ TimestampSpec spec = new TimestampSpec(null, null, DateTimes.EPOCH);
Assert.assertEquals(
- new DateTime("1970-01-01"),
+ DateTimes.of("1970-01-01"),
spec.extractTimestamp(ImmutableMap.of("dim", "foo"))
);
}
diff --git a/api/src/test/java/io/druid/timeline/DataSegmentTest.java b/api/src/test/java/io/druid/timeline/DataSegmentTest.java
index 5488e97d965..b5c60d717bd 100644
--- a/api/src/test/java/io/druid/timeline/DataSegmentTest.java
+++ b/api/src/test/java/io/druid/timeline/DataSegmentTest.java
@@ -19,7 +19,6 @@
package io.druid.timeline;
-import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -28,11 +27,13 @@ import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import io.druid.TestObjectMapper;
import io.druid.data.input.InputRow;
+import io.druid.java.util.common.jackson.JacksonUtils;
+import io.druid.java.util.common.DateTimes;
+import io.druid.java.util.common.Intervals;
import io.druid.timeline.partition.NoneShardSpec;
import io.druid.timeline.partition.PartitionChunk;
import io.druid.timeline.partition.ShardSpec;
import io.druid.timeline.partition.ShardSpecLookup;
-import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.junit.Assert;
import org.junit.Test;
@@ -90,7 +91,7 @@ public class DataSegmentTest
public void testV1Serialization() throws Exception
{
- final Interval interval = new Interval("2011-10-01/2011-10-02");
+ final Interval interval = Intervals.of("2011-10-01/2011-10-02");
final ImmutableMap loadSpec = ImmutableMap.of("something", "or_other");
DataSegment segment = new DataSegment(
@@ -107,9 +108,7 @@ public class DataSegmentTest
final Map objectMap = mapper.readValue(
mapper.writeValueAsString(segment),
- new TypeReference