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 04dbe96707e7..006bd5a67956 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 4f4c640f1040..a6f403cf355d 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 @@ * 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 2494c13ea716..75049ea89116 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 @@ 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 @@ * 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 a0fc5e2468fa..64a2b11d9370 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 @@ * 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 05f72cc8609b..d22f1a59a4f6 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 @@ * 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 40164571bc19..b3f792711f5b 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 @@ * 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 4d83b2659558..d6f3647ed17d 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,7 @@ package io.druid.data.input; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.DateTimes; import org.joda.time.DateTime; @@ -27,6 +28,7 @@ /** */ +@PublicApi public class MapBasedInputRow extends MapBasedRow implements InputRow { private final List 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 ff80d65321d3..7a8ba07a44a1 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,7 @@ 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; @@ -33,6 +34,7 @@ /** */ +@PublicApi public class MapBasedRow implements Row { private static final Pattern LONG_PAT = Pattern.compile("[-|+]?\\d+"); 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 f698c02dd687..f5462ff5bda7 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 @@ 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 @@ * 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 05e1aeec4f92..a31d1b3a2240 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.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 fd9acb62be1c..fb61f5b977b6 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.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 ecbfb9788871..3d48a95abe71 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.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.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 13c7cc18edf5..dcf369ca959d 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 @@ 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 17600ee18f47..177a2b39a75a 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 @@ 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 81ce73b94a44..d58dac4aa4a4 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.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 620f8109bd15..499f61d5bfee 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 @@ 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 96c06237d9b1..7efc397f5f44 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 @@ 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 a90978bf2b18..926328c701aa 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.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 8f83d25b714e..ffb767bd7acc 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 @@ 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 @@ /** */ +@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 1d6b220ffa76..30315d6fdebf 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 @@ 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 2846977944c2..2b9ea4162c48 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.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 @@ * 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 149f72c9be70..956abc7abcd6 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 @@ 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 a837928a2a77..d7aeab313c26 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.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 9c0163a4fb5b..51520eae749e 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.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 4e9b5f64f980..c3a9cfd64d80 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.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 @@ * * @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 452621df8124..5acf6466be6a 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 @@ @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 2d9968cdc3cb..2dc340dd84e9 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.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 42a34979a3d8..19914b0f0f3d 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.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 e062aa3994b4..53d4d8f33e9d 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 @@ @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 ff88784898a9..02a7ff15d984 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 @@ @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 fddeb98c3097..fbcdaaaa4ad8 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.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 @@ * 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 000000000000..9dc02e170442 --- /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 25222ce4bf31..84de20132610 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 @@ @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 465840cc7d0e..948bd5760632 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 @@ @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 73dac864e9a5..4371554977ad 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 @@ @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 000000000000..f398dfe81a2d --- /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 e6123fbe188d..f5a8b348c4e2 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 @@ @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 136885a4f461..babfb5a68d71 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 @@ @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 9015dca45bec..89bb3d857688 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 getJacksonModules(); diff --git a/api/src/main/java/io/druid/js/JavaScriptConfig.java b/api/src/main/java/io/druid/js/JavaScriptConfig.java index 6b62431aa88d..7dc6bb1b2fb1 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 @@ 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 f1b495f9a134..448eaf0c5039 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 @@ 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.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 b08365cce9ee..2776bfb4aa45 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 ef4dafbdba92..937a42e72c23 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 @@ * 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 ba9b879587a8..c26a73daeb10 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 81080585cdf8..6b59c87e4217 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 46f051138a5f..fe2d089b0ece 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 @@ /** * 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 3076b5e7c1af..b9bf810f72ce 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.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 d1945e160855..e026ded7090c 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 2ac69944a74f..3bd388dc9f95 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 9ae45a3ac425..1a5718fc54ba 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 @@ /** * 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 4ba760a79b8d..3c413303c704 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 @@ 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 f03e46ad0c4e..7a63f640a8fb 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 3fc16d46f984..9b30e4f2be98 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 ccd9a99cdcbd..0e60ffcf7c76 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 @@ 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 db76b924e9e0..383c3559ae1a 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 74322c8c3c6a..0b4b2f9fe5c8 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.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 @@ /** */ +@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 eced6598d837..349bbceda030 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 @@ /** * identifier to DataSegment. */ +@PublicApi public class DataSegmentUtils { private static final Logger LOGGER = new Logger(DataSegmentUtils.class); 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 b76a01941cf3..466c9b145825 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.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 3d628dce1cf1..6a551e319e0d 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 d6cec40db15c..883aae65b8c4 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/data/input/impl/JSONLowercaseParseSpecTest.java b/api/src/test/java/io/druid/data/input/impl/JSONLowercaseParseSpecTest.java index b2e6f4681adb..d8fc9fde77e3 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 a1e95c028ada..daf58c648af9 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/common/src/main/java/io/druid/metadata/PasswordProvider.java b/common/src/main/java/io/druid/metadata/PasswordProvider.java index ec8855aeb214..5d2928cb0547 100644 --- a/common/src/main/java/io/druid/metadata/PasswordProvider.java +++ b/common/src/main/java/io/druid/metadata/PasswordProvider.java @@ -21,11 +21,13 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.druid.guice.annotations.ExtensionPoint; /** * Implement this for different ways to (optionally securely) access secrets. */ +@ExtensionPoint @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = DefaultPasswordProvider.class) @JsonSubTypes(value = { @JsonSubTypes.Type(name = "default", value = DefaultPasswordProvider.class), diff --git a/common/src/main/java/io/druid/timeline/LogicalSegment.java b/common/src/main/java/io/druid/timeline/LogicalSegment.java index c053b7b655c7..f5e5c4f9f351 100644 --- a/common/src/main/java/io/druid/timeline/LogicalSegment.java +++ b/common/src/main/java/io/druid/timeline/LogicalSegment.java @@ -19,8 +19,10 @@ package io.druid.timeline; +import io.druid.guice.annotations.PublicApi; import org.joda.time.Interval; +@PublicApi public interface LogicalSegment { public Interval getInterval(); diff --git a/docs/content/development/modules.md b/docs/content/development/modules.md index 33bfc1045186..be3773bfaf15 100644 --- a/docs/content/development/modules.md +++ b/docs/content/development/modules.md @@ -10,12 +10,21 @@ Druid uses a module system that allows for the addition of extensions at runtime Druid's extensions leverage Guice in order to add things at runtime. Basically, Guice is a framework for Dependency Injection, but we use it to hold the expected object graph of the Druid process. Extensions can make any changes they want/need to the object graph via adding Guice bindings. While the extensions actually give you the capability to change almost anything however you want, in general, we expect people to want to extend one of the things listed below. This means that we honor our [versioning strategy](./versioning.html) for changes that affect the interfaces called out on this page, but other interfaces are deemed "internal" and can be changed in an incompatible manner even between patch releases. -1. Add a new deep storage implementation -1. Add a new Firehose -1. Add Aggregators -1. Add Complex metrics -1. Add new Query types -1. Add new Jersey resources +1. Add a new deep storage implementation by extending the `io.druid.segment.loading.DataSegment*` and + `io.druid.tasklogs.TaskLog*` classes. +1. Add a new Firehose by extending `io.druid.data.input.FirehoseFactory`. +1. Add a new input parser by extending `io.druid.data.input.impl.InputRowParser`. +1. Add a new string-based input format by extending `io.druid.data.input.impl.ParseSpec`. +1. Add Aggregators by extending `io.druid.query.aggregation.AggregatorFactory`, `io.druid.query.aggregation.Aggregator`, + and `io.druid.query.aggregation.BufferAggregator`. +1. Add PostAggregators by extending `io.druid.query.aggregation.PostAggregator`. +1. Add ExtractionFns by extending `io.druid.query.extraction.ExtractionFn`. +1. Add Complex metrics by extending `io.druid.segment.serde.ComplexMetricsSerde`. +1. Add new Query types by extending `io.druid.query.QueryRunnerFactory`, `io.druid.query.QueryToolChest`, and + `io.druid.query.Query`. +1. Add new Jersey resources by calling `Jerseys.addResource(binder, clazz)`. +1. Add new Jetty filters by extending `io.druid.server.initialization.jetty.ServletFilterHolder`. +1. Add new secret providers by extending `io.druid.metadata.PasswordProvider`. 1. Bundle your extension with all the other Druid extensions Extensions are added to the system via an implementation of `io.druid.initialization.DruidModule`. diff --git a/processing/src/main/java/io/druid/query/BaseQuery.java b/processing/src/main/java/io/druid/query/BaseQuery.java index 8869508807f7..a7cd66d11551 100644 --- a/processing/src/main/java/io/druid/query/BaseQuery.java +++ b/processing/src/main/java/io/druid/query/BaseQuery.java @@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.collect.Ordering; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.query.spec.QuerySegmentSpec; import org.joda.time.Duration; import org.joda.time.Interval; @@ -33,6 +34,7 @@ /** */ +@ExtensionPoint public abstract class BaseQuery> implements Query { public static void checkInterrupted() diff --git a/processing/src/main/java/io/druid/query/BySegmentResultValue.java b/processing/src/main/java/io/druid/query/BySegmentResultValue.java index a8758d443396..6259a3401f33 100644 --- a/processing/src/main/java/io/druid/query/BySegmentResultValue.java +++ b/processing/src/main/java/io/druid/query/BySegmentResultValue.java @@ -19,12 +19,14 @@ package io.druid.query; +import io.druid.guice.annotations.PublicApi; import org.joda.time.Interval; import java.util.List; /** */ +@PublicApi public interface BySegmentResultValue { public List getResults(); diff --git a/processing/src/main/java/io/druid/query/CacheStrategy.java b/processing/src/main/java/io/druid/query/CacheStrategy.java index 8e14947b4065..95681dd1b067 100644 --- a/processing/src/main/java/io/druid/query/CacheStrategy.java +++ b/processing/src/main/java/io/druid/query/CacheStrategy.java @@ -21,11 +21,13 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.base.Function; +import io.druid.guice.annotations.ExtensionPoint; import java.util.concurrent.ExecutorService; /** */ +@ExtensionPoint public interface CacheStrategy> { /** diff --git a/processing/src/main/java/io/druid/query/GenericQueryMetricsFactory.java b/processing/src/main/java/io/druid/query/GenericQueryMetricsFactory.java index 5882d9c79222..6fd1e79174f6 100644 --- a/processing/src/main/java/io/druid/query/GenericQueryMetricsFactory.java +++ b/processing/src/main/java/io/druid/query/GenericQueryMetricsFactory.java @@ -19,6 +19,8 @@ package io.druid.query; +import io.druid.guice.annotations.PublicApi; + /** * This factory is used for DI of custom {@link QueryMetrics} implementations for all query types, which don't (yet) * need to emit custom dimensions and/or metrics, i. e. they are good with the generic {@link QueryMetrics} interface. @@ -32,7 +34,11 @@ * * And then setting property: * druid.query.generic.queryMetricsFactory=myCustomGenericQueryMetricsFactory + * + * Unlike {@link QueryMetrics} itself, this interface is considered stable and is expected to be injected into custom + * Query extensions that do not want to worry about the potential instability of {@link QueryMetrics}. */ +@PublicApi public interface GenericQueryMetricsFactory { /** diff --git a/processing/src/main/java/io/druid/query/IntervalChunkingQueryRunnerDecorator.java b/processing/src/main/java/io/druid/query/IntervalChunkingQueryRunnerDecorator.java index 9a2df39a3650..5f7e10c5bccf 100644 --- a/processing/src/main/java/io/druid/query/IntervalChunkingQueryRunnerDecorator.java +++ b/processing/src/main/java/io/druid/query/IntervalChunkingQueryRunnerDecorator.java @@ -22,6 +22,7 @@ import com.google.inject.Inject; import com.metamx.emitter.service.ServiceEmitter; import io.druid.guice.annotations.Processing; +import io.druid.guice.annotations.PublicApi; import java.util.concurrent.ExecutorService; @@ -40,6 +41,7 @@ public IntervalChunkingQueryRunnerDecorator(@Processing ExecutorService executor this.emitter = emitter; } + @PublicApi public QueryRunner decorate(QueryRunner delegate, QueryToolChest> toolChest) { return new IntervalChunkingQueryRunner(delegate, (QueryToolChest>) toolChest, diff --git a/processing/src/main/java/io/druid/query/Queries.java b/processing/src/main/java/io/druid/query/Queries.java index 519ef2acc65c..b372407d50d1 100644 --- a/processing/src/main/java/io/druid/query/Queries.java +++ b/processing/src/main/java/io/druid/query/Queries.java @@ -22,6 +22,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import io.druid.guice.annotations.PublicApi; import io.druid.query.aggregation.AggregatorFactory; import io.druid.query.aggregation.PostAggregator; @@ -34,6 +35,7 @@ /** */ +@PublicApi public class Queries { public static List decoratePostAggregators( diff --git a/processing/src/main/java/io/druid/query/Query.java b/processing/src/main/java/io/druid/query/Query.java index e8c62962f539..9e0d8a0f658d 100644 --- a/processing/src/main/java/io/druid/query/Query.java +++ b/processing/src/main/java/io/druid/query/Query.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.google.common.collect.Ordering; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.query.datasourcemetadata.DataSourceMetadataQuery; import io.druid.query.filter.DimFilter; import io.druid.query.groupby.GroupByQuery; @@ -38,6 +39,7 @@ import java.util.List; import java.util.Map; +@ExtensionPoint @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "queryType") @JsonSubTypes(value = { @JsonSubTypes.Type(name = Query.TIMESERIES, value = TimeseriesQuery.class), diff --git a/processing/src/main/java/io/druid/query/QueryContexts.java b/processing/src/main/java/io/druid/query/QueryContexts.java index 2e9dfdd9b684..b56812d8b0e5 100644 --- a/processing/src/main/java/io/druid/query/QueryContexts.java +++ b/processing/src/main/java/io/druid/query/QueryContexts.java @@ -21,9 +21,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.IAE; import io.druid.java.util.common.ISE; +@PublicApi public class QueryContexts { public static final String PRIORITY_KEY = "priority"; diff --git a/processing/src/main/java/io/druid/query/QueryMetrics.java b/processing/src/main/java/io/druid/query/QueryMetrics.java index 86c29fe8b726..7eab88c5af1a 100644 --- a/processing/src/main/java/io/druid/query/QueryMetrics.java +++ b/processing/src/main/java/io/druid/query/QueryMetrics.java @@ -78,6 +78,9 @@ * dimension or metric is useful and not very expensive to process and store then emit, skip (see above Goals, 1.) * otherwise. * + *

This interface can be extended, but is not marked as an {@code ExtensionPoint}, because it may change in breaking + * ways even in minor releases. + * *

If implementors of custom QueryMetrics don't want to fix builds on every Druid release (e. g. if they want to add * a single dimension to emitted events and don't want to alter other dimensions and emitted metrics), they could * inherit their custom QueryMetrics from {@link DefaultQueryMetrics} or query-specific default implementation class, diff --git a/processing/src/main/java/io/druid/query/QueryPlus.java b/processing/src/main/java/io/druid/query/QueryPlus.java index c6cfe6f89f88..63d2e8abe877 100644 --- a/processing/src/main/java/io/druid/query/QueryPlus.java +++ b/processing/src/main/java/io/druid/query/QueryPlus.java @@ -20,6 +20,7 @@ package io.druid.query; import com.google.common.base.Preconditions; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.guava.Sequence; import io.druid.query.spec.QuerySegmentSpec; @@ -30,6 +31,7 @@ * An immutable composite object of {@link Query} + extra stuff needed in {@link QueryRunner}s. This "extra stuff" * is only {@link QueryMetrics} yet. */ +@PublicApi public final class QueryPlus { /** diff --git a/processing/src/main/java/io/druid/query/QueryRunner.java b/processing/src/main/java/io/druid/query/QueryRunner.java index cf9366451e07..b9cbf5244f66 100644 --- a/processing/src/main/java/io/druid/query/QueryRunner.java +++ b/processing/src/main/java/io/druid/query/QueryRunner.java @@ -19,10 +19,12 @@ package io.druid.query; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.java.util.common.guava.Sequence; import java.util.Map; +@ExtensionPoint public interface QueryRunner { /** diff --git a/processing/src/main/java/io/druid/query/QueryRunnerFactory.java b/processing/src/main/java/io/druid/query/QueryRunnerFactory.java index 3eb2eae4e0a3..cc1419be978c 100644 --- a/processing/src/main/java/io/druid/query/QueryRunnerFactory.java +++ b/processing/src/main/java/io/druid/query/QueryRunnerFactory.java @@ -19,6 +19,7 @@ package io.druid.query; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.segment.Segment; import java.util.concurrent.ExecutorService; @@ -26,6 +27,7 @@ /** * An interface that defines the nitty gritty implementation detauls of a Query on a Segment */ +@ExtensionPoint public interface QueryRunnerFactory> { /** diff --git a/processing/src/main/java/io/druid/query/QueryToolChest.java b/processing/src/main/java/io/druid/query/QueryToolChest.java index c41bb86c4388..9cb78c5d98c0 100644 --- a/processing/src/main/java/io/druid/query/QueryToolChest.java +++ b/processing/src/main/java/io/druid/query/QueryToolChest.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.base.Function; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.query.aggregation.MetricManipulationFn; import io.druid.timeline.LogicalSegment; @@ -28,10 +29,9 @@ import java.util.List; /** - * The broker-side (also used by server in some cases) API for a specific Query type. This API is still undergoing - * evolution and is only semi-stable, so proprietary Query implementations should be ready for the potential - * maintenance burden when upgrading versions. + * The broker-side (also used by server in some cases) API for a specific Query type. */ +@ExtensionPoint public abstract class QueryToolChest> { /** diff --git a/processing/src/main/java/io/druid/query/Result.java b/processing/src/main/java/io/druid/query/Result.java index 0a23ad625f4c..10afea9c23b7 100644 --- a/processing/src/main/java/io/druid/query/Result.java +++ b/processing/src/main/java/io/druid/query/Result.java @@ -21,12 +21,14 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.druid.guice.annotations.PublicApi; import org.joda.time.DateTime; import java.util.function.Function; /** */ +@PublicApi public class Result implements Comparable> { public static String MISSING_SEGMENTS_KEY = "missingSegments"; diff --git a/processing/src/main/java/io/druid/query/ResultGranularTimestampComparator.java b/processing/src/main/java/io/druid/query/ResultGranularTimestampComparator.java index 98953a5687ce..8bf6c9e8fede 100644 --- a/processing/src/main/java/io/druid/query/ResultGranularTimestampComparator.java +++ b/processing/src/main/java/io/druid/query/ResultGranularTimestampComparator.java @@ -21,12 +21,14 @@ import com.google.common.collect.Ordering; import com.google.common.primitives.Longs; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.granularity.Granularity; import java.util.Comparator; /** */ +@PublicApi public class ResultGranularTimestampComparator implements Comparator> { private final Granularity gran; diff --git a/processing/src/main/java/io/druid/query/ResultMergeQueryRunner.java b/processing/src/main/java/io/druid/query/ResultMergeQueryRunner.java index 04c6e550dd74..7840a7de5d5a 100644 --- a/processing/src/main/java/io/druid/query/ResultMergeQueryRunner.java +++ b/processing/src/main/java/io/druid/query/ResultMergeQueryRunner.java @@ -21,6 +21,7 @@ import com.google.common.collect.Ordering; import io.druid.common.guava.CombiningSequence; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.guava.Sequence; import io.druid.java.util.common.guava.nary.BinaryFn; @@ -28,6 +29,7 @@ /** */ +@PublicApi public abstract class ResultMergeQueryRunner extends BySegmentSkippingQueryRunner { public ResultMergeQueryRunner( diff --git a/processing/src/main/java/io/druid/query/aggregation/Aggregator.java b/processing/src/main/java/io/druid/query/aggregation/Aggregator.java index 847fdcb67838..d7fba1e3c5cd 100644 --- a/processing/src/main/java/io/druid/query/aggregation/Aggregator.java +++ b/processing/src/main/java/io/druid/query/aggregation/Aggregator.java @@ -19,6 +19,8 @@ package io.druid.query.aggregation; +import io.druid.guice.annotations.ExtensionPoint; + import java.io.Closeable; /** @@ -30,6 +32,7 @@ * to aggregate(). This is currently (as of this documentation) implemented through the use of {@link * io.druid.segment.ColumnValueSelector} objects. */ +@ExtensionPoint public interface Aggregator extends Closeable { void aggregate(); diff --git a/processing/src/main/java/io/druid/query/aggregation/AggregatorFactory.java b/processing/src/main/java/io/druid/query/aggregation/AggregatorFactory.java index 9a37e1629556..f4e67c34e26b 100644 --- a/processing/src/main/java/io/druid/query/aggregation/AggregatorFactory.java +++ b/processing/src/main/java/io/druid/query/aggregation/AggregatorFactory.java @@ -19,6 +19,7 @@ package io.druid.query.aggregation; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.java.util.common.Cacheable; import io.druid.java.util.common.UOE; import io.druid.java.util.common.logger.Logger; @@ -35,6 +36,7 @@ * max, sum of metric columns, or cardinality of dimension columns (see {@link * io.druid.query.aggregation.cardinality.CardinalityAggregatorFactory}). */ +@ExtensionPoint public abstract class AggregatorFactory implements Cacheable { private static final Logger log = new Logger(AggregatorFactory.class); diff --git a/processing/src/main/java/io/druid/query/aggregation/AggregatorUtil.java b/processing/src/main/java/io/druid/query/aggregation/AggregatorUtil.java index 399880188ee3..d8adbe3182a5 100644 --- a/processing/src/main/java/io/druid/query/aggregation/AggregatorUtil.java +++ b/processing/src/main/java/io/druid/query/aggregation/AggregatorUtil.java @@ -20,6 +20,7 @@ package io.druid.query.aggregation; import com.google.common.collect.Lists; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.Pair; import io.druid.math.expr.ExprMacroTable; import io.druid.math.expr.Parser; @@ -34,6 +35,7 @@ import java.util.List; import java.util.Set; +@PublicApi public class AggregatorUtil { public static final byte STRING_SEPARATOR = (byte) 0xFF; diff --git a/processing/src/main/java/io/druid/query/aggregation/BufferAggregator.java b/processing/src/main/java/io/druid/query/aggregation/BufferAggregator.java index 9dc9acb32675..cdddd7629f2d 100644 --- a/processing/src/main/java/io/druid/query/aggregation/BufferAggregator.java +++ b/processing/src/main/java/io/druid/query/aggregation/BufferAggregator.java @@ -19,6 +19,7 @@ package io.druid.query.aggregation; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.query.monomorphicprocessing.CalledFromHotLoop; import io.druid.query.monomorphicprocessing.HotLoopCallee; import io.druid.query.monomorphicprocessing.RuntimeShapeInspector; @@ -33,6 +34,7 @@ * Thus, an Aggregator can be thought of as a closure over some other thing that is stateful and changes between calls * to aggregate(...). */ +@ExtensionPoint public interface BufferAggregator extends HotLoopCallee { /** diff --git a/processing/src/main/java/io/druid/query/aggregation/MetricManipulationFn.java b/processing/src/main/java/io/druid/query/aggregation/MetricManipulationFn.java index 15f391a43dbe..19812e3f8a97 100644 --- a/processing/src/main/java/io/druid/query/aggregation/MetricManipulationFn.java +++ b/processing/src/main/java/io/druid/query/aggregation/MetricManipulationFn.java @@ -19,8 +19,11 @@ package io.druid.query.aggregation; +import io.druid.guice.annotations.PublicApi; + /** */ +@PublicApi public interface MetricManipulationFn { public Object manipulate(AggregatorFactory factory, Object object); diff --git a/processing/src/main/java/io/druid/query/aggregation/PostAggregator.java b/processing/src/main/java/io/druid/query/aggregation/PostAggregator.java index 5366d5e546a0..171d4f39ef18 100644 --- a/processing/src/main/java/io/druid/query/aggregation/PostAggregator.java +++ b/processing/src/main/java/io/druid/query/aggregation/PostAggregator.java @@ -19,6 +19,7 @@ package io.druid.query.aggregation; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.java.util.common.Cacheable; import java.util.Comparator; @@ -28,6 +29,7 @@ /** * Functionally similar to an Aggregator. See the Aggregator interface for more comments. */ +@ExtensionPoint public interface PostAggregator extends Cacheable { Set getDependentFields(); diff --git a/processing/src/main/java/io/druid/query/cache/CacheKeyBuilder.java b/processing/src/main/java/io/druid/query/cache/CacheKeyBuilder.java index 81a89e4e936b..530f2725bc14 100644 --- a/processing/src/main/java/io/druid/query/cache/CacheKeyBuilder.java +++ b/processing/src/main/java/io/druid/query/cache/CacheKeyBuilder.java @@ -26,6 +26,7 @@ import com.google.common.primitives.Floats; import com.google.common.primitives.Ints; import com.google.common.primitives.UnsignedBytes; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.StringUtils; import io.druid.java.util.common.Cacheable; @@ -50,6 +51,7 @@ * +--------------------------------------------------------+ * */ +@PublicApi public class CacheKeyBuilder { static final byte BYTE_KEY = 0; diff --git a/processing/src/main/java/io/druid/query/dimension/DimensionSpec.java b/processing/src/main/java/io/druid/query/dimension/DimensionSpec.java index 7749be3120ef..7a98ffd5edb8 100644 --- a/processing/src/main/java/io/druid/query/dimension/DimensionSpec.java +++ b/processing/src/main/java/io/druid/query/dimension/DimensionSpec.java @@ -27,6 +27,8 @@ import io.druid.segment.column.ValueType; /** + * Provides information about a dimension for a grouping query, like topN or groupBy. Note that this is not annotated + * with {@code PublicApi}, since it is not meant to be stable for usage by non-built-in queries. */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = LegacyDimensionSpec.class) @JsonSubTypes(value = { diff --git a/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java index 0bfe2033fc71..b3e7cb39098f 100644 --- a/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.query.lookup.LookupExtractionFn; import io.druid.query.lookup.RegisteredLookupExtractionFn; @@ -28,6 +29,7 @@ /** */ +@ExtensionPoint @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes(value = { @JsonSubTypes.Type(name = "time", value = TimeDimExtractionFn.class), diff --git a/processing/src/main/java/io/druid/segment/GenericColumnSerializer.java b/processing/src/main/java/io/druid/segment/GenericColumnSerializer.java index 19f8b451b02d..474d7dafe524 100644 --- a/processing/src/main/java/io/druid/segment/GenericColumnSerializer.java +++ b/processing/src/main/java/io/druid/segment/GenericColumnSerializer.java @@ -19,12 +19,14 @@ package io.druid.segment; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.java.util.common.io.smoosh.FileSmoosher; import java.io.Closeable; import java.io.IOException; import java.nio.channels.WritableByteChannel; +@ExtensionPoint public interface GenericColumnSerializer extends Closeable { public void open() throws IOException; diff --git a/processing/src/main/java/io/druid/segment/Metadata.java b/processing/src/main/java/io/druid/segment/Metadata.java index 3ac724e8f0c5..e7cf31354f2f 100644 --- a/processing/src/main/java/io/druid/segment/Metadata.java +++ b/processing/src/main/java/io/druid/segment/Metadata.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.druid.data.input.impl.TimestampSpec; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.granularity.Granularity; import io.druid.query.aggregation.AggregatorFactory; @@ -33,6 +34,7 @@ /** */ +@PublicApi public class Metadata { // container is used for arbitrary key-value pairs in segment metadata e.g. diff --git a/processing/src/main/java/io/druid/segment/QueryableIndex.java b/processing/src/main/java/io/druid/segment/QueryableIndex.java index ee50675f4b86..fcfd6b2395a1 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndex.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndex.java @@ -28,6 +28,11 @@ import java.util.Map; /** + * Direct interface to memory mapped segments. Not a public API for extensions; site specific queries should be + * using {@link StorageAdapter}. + * + * @see QueryableIndexStorageAdapter for query path adapter + * @see QueryableIndexIndexableAdapter for indexing path adapter */ public interface QueryableIndex extends ColumnSelector, Closeable { diff --git a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java index fb0f7eb6fe55..550a009bedea 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java @@ -173,12 +173,6 @@ public ColumnCapabilities getColumnCapabilities(String column) return getColumnCapabilites(index, column); } - @Override - public Map getDimensionHandlers() - { - return index.getDimensionHandlers(); - } - @Override public String getColumnTypeName(String columnName) { diff --git a/processing/src/main/java/io/druid/segment/Segment.java b/processing/src/main/java/io/druid/segment/Segment.java index aef3dc865132..4c38a7f36b49 100644 --- a/processing/src/main/java/io/druid/segment/Segment.java +++ b/processing/src/main/java/io/druid/segment/Segment.java @@ -19,12 +19,14 @@ package io.druid.segment; +import io.druid.guice.annotations.PublicApi; import org.joda.time.Interval; import java.io.Closeable; /** */ +@PublicApi public interface Segment extends Closeable { public String getIdentifier(); diff --git a/processing/src/main/java/io/druid/segment/StorageAdapter.java b/processing/src/main/java/io/druid/segment/StorageAdapter.java index 82b181a9bed1..62e3dfa250d2 100644 --- a/processing/src/main/java/io/druid/segment/StorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/StorageAdapter.java @@ -19,16 +19,17 @@ package io.druid.segment; +import io.druid.guice.annotations.PublicApi; import io.druid.segment.column.ColumnCapabilities; import io.druid.segment.data.Indexed; import org.joda.time.DateTime; import org.joda.time.Interval; import javax.annotation.Nullable; -import java.util.Map; /** */ +@PublicApi public interface StorageAdapter extends CursorFactory { public String getSegmentIdentifier(); @@ -63,8 +64,6 @@ public interface StorageAdapter extends CursorFactory @Nullable public ColumnCapabilities getColumnCapabilities(String column); - public Map getDimensionHandlers(); - /** * Like {@link ColumnCapabilities#getType()}, but may return a more descriptive string for complex columns. * @param column column name diff --git a/processing/src/main/java/io/druid/segment/data/Indexed.java b/processing/src/main/java/io/druid/segment/data/Indexed.java index 1f6ee2ebf1ca..a10cfd226211 100644 --- a/processing/src/main/java/io/druid/segment/data/Indexed.java +++ b/processing/src/main/java/io/druid/segment/data/Indexed.java @@ -19,9 +19,11 @@ package io.druid.segment.data; +import io.druid.guice.annotations.PublicApi; import io.druid.query.monomorphicprocessing.CalledFromHotLoop; import io.druid.query.monomorphicprocessing.HotLoopCallee; +@PublicApi public interface Indexed extends Iterable, HotLoopCallee { Class getClazz(); diff --git a/processing/src/main/java/io/druid/segment/data/ObjectStrategy.java b/processing/src/main/java/io/druid/segment/data/ObjectStrategy.java index a0ab34ba6bd2..dfcb60ed4434 100644 --- a/processing/src/main/java/io/druid/segment/data/ObjectStrategy.java +++ b/processing/src/main/java/io/druid/segment/data/ObjectStrategy.java @@ -19,9 +19,12 @@ package io.druid.segment.data; +import io.druid.guice.annotations.ExtensionPoint; + import java.nio.ByteBuffer; import java.util.Comparator; +@ExtensionPoint public interface ObjectStrategy extends Comparator { public Class getClazz(); diff --git a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java index e23b0e4d0fb6..50cf97df240d 100644 --- a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java @@ -35,7 +35,6 @@ import io.druid.query.monomorphicprocessing.RuntimeShapeInspector; import io.druid.segment.Capabilities; import io.druid.segment.Cursor; -import io.druid.segment.DimensionHandler; import io.druid.segment.DimensionIndexer; import io.druid.segment.DimensionSelector; import io.druid.segment.DoubleColumnSelector; @@ -64,7 +63,6 @@ import javax.annotation.Nullable; import java.util.Iterator; -import java.util.Map; /** */ @@ -173,12 +171,6 @@ public ColumnCapabilities getColumnCapabilities(String column) return index.getCapabilities(column); } - @Override - public Map getDimensionHandlers() - { - return index.getDimensionHandlers(); - } - @Override public String getColumnTypeName(String column) { diff --git a/processing/src/main/java/io/druid/segment/serde/ComplexColumnSerializer.java b/processing/src/main/java/io/druid/segment/serde/ComplexColumnSerializer.java index 9b97ceaa9022..a76878491009 100644 --- a/processing/src/main/java/io/druid/segment/serde/ComplexColumnSerializer.java +++ b/processing/src/main/java/io/druid/segment/serde/ComplexColumnSerializer.java @@ -19,6 +19,7 @@ package io.druid.segment.serde; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.StringUtils; import io.druid.java.util.common.io.smoosh.FileSmoosher; import io.druid.segment.GenericColumnSerializer; @@ -46,6 +47,7 @@ public ComplexColumnSerializer( this.strategy = strategy; } + @PublicApi public static ComplexColumnSerializer create( IOPeon ioPeon, String filenameBase, diff --git a/processing/src/main/java/io/druid/segment/serde/ComplexMetricExtractor.java b/processing/src/main/java/io/druid/segment/serde/ComplexMetricExtractor.java index 243b0999fcbb..37a8ea342489 100644 --- a/processing/src/main/java/io/druid/segment/serde/ComplexMetricExtractor.java +++ b/processing/src/main/java/io/druid/segment/serde/ComplexMetricExtractor.java @@ -20,9 +20,11 @@ package io.druid.segment.serde; import io.druid.data.input.InputRow; +import io.druid.guice.annotations.ExtensionPoint; /** */ +@ExtensionPoint public interface ComplexMetricExtractor { public Class extractedClass(); diff --git a/processing/src/main/java/io/druid/segment/serde/ComplexMetricSerde.java b/processing/src/main/java/io/druid/segment/serde/ComplexMetricSerde.java index 5a0d3418ac40..e0b2aaa662d8 100644 --- a/processing/src/main/java/io/druid/segment/serde/ComplexMetricSerde.java +++ b/processing/src/main/java/io/druid/segment/serde/ComplexMetricSerde.java @@ -20,6 +20,7 @@ package io.druid.segment.serde; import com.google.common.base.Function; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.segment.GenericColumnSerializer; import io.druid.segment.column.ColumnBuilder; import io.druid.segment.data.IOPeon; @@ -29,6 +30,7 @@ /** */ +@ExtensionPoint public abstract class ComplexMetricSerde { public abstract String getTypeName(); diff --git a/processing/src/main/java/io/druid/segment/serde/LargeColumnSupportedComplexColumnSerializer.java b/processing/src/main/java/io/druid/segment/serde/LargeColumnSupportedComplexColumnSerializer.java index 888912da9b7e..f3c12d8a919f 100644 --- a/processing/src/main/java/io/druid/segment/serde/LargeColumnSupportedComplexColumnSerializer.java +++ b/processing/src/main/java/io/druid/segment/serde/LargeColumnSupportedComplexColumnSerializer.java @@ -19,6 +19,7 @@ package io.druid.segment.serde; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.StringUtils; import io.druid.java.util.common.io.smoosh.FileSmoosher; import io.druid.segment.GenericColumnSerializer; @@ -58,6 +59,7 @@ public LargeColumnSupportedComplexColumnSerializer( this.columnSize = columnSize; } + @PublicApi public static LargeColumnSupportedComplexColumnSerializer create( IOPeon ioPeon, String filenameBase, diff --git a/server/src/main/java/io/druid/server/initialization/jetty/ServletFilterHolder.java b/server/src/main/java/io/druid/server/initialization/jetty/ServletFilterHolder.java index d40a9bfba540..5566e98405ee 100644 --- a/server/src/main/java/io/druid/server/initialization/jetty/ServletFilterHolder.java +++ b/server/src/main/java/io/druid/server/initialization/jetty/ServletFilterHolder.java @@ -19,6 +19,8 @@ package io.druid.server.initialization.jetty; +import io.druid.guice.annotations.ExtensionPoint; + import javax.servlet.DispatcherType; import javax.servlet.Filter; import java.util.EnumSet; @@ -33,6 +35,7 @@ * Note that some of the druid nodes (router for example) use async servlets and your filter * implementation should be able to handle those requests properly. */ +@ExtensionPoint public interface ServletFilterHolder {