From 202c51e19d6e9fa44feb16eeee7c32597e5fbafa Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Sat, 17 Jun 2017 15:16:04 -0700 Subject: [PATCH 1/9] Add @ExtensionPoint and @PublicApi annotations. --- .../java/io/druid/data/input/Committer.java | 16 +++--- .../java/io/druid/data/input/Firehose.java | 3 ++ .../io/druid/data/input/FirehoseFactory.java | 2 + .../druid/data/input/FirehoseFactoryV2.java | 3 +- .../java/io/druid/data/input/FirehoseV2.java | 3 ++ .../java/io/druid/data/input/InputRow.java | 6 ++- .../io/druid/data/input/MapBasedInputRow.java | 2 + .../java/io/druid/data/input/MapBasedRow.java | 4 +- .../main/java/io/druid/data/input/Row.java | 2 + .../main/java/io/druid/data/input/Rows.java | 19 ------- .../druid/data/input/impl/DimensionsSpec.java | 1 - .../druid/data/input/impl/InputRowParser.java | 2 + .../input/impl/JSONLowercaseParseSpec.java | 1 - .../druid/data/input/impl/JSONParseSpec.java | 1 - .../data/input/impl/JavaScriptParseSpec.java | 1 - .../data/input/impl/MapInputRowParser.java | 2 - .../io/druid/data/input/impl/ParseSpec.java | 2 +- .../druid/data/input/impl/RegexParseSpec.java | 1 - .../data/input/impl/StringInputRowParser.java | 2 + .../druid/data/input/impl/TimestampSpec.java | 2 - api/src/main/java/io/druid/guice/Binders.java | 4 +- .../io/druid/guice/ConditionalMultibind.java | 2 + .../io/druid/guice/DruidGuiceExtensions.java | 2 + .../main/java/io/druid/guice/DruidScopes.java | 2 + api/src/main/java/io/druid/guice/Jerseys.java | 2 + .../io/druid/guice/JsonConfigProvider.java | 2 + .../java/io/druid/guice/LazySingleton.java | 2 + .../java/io/druid/guice/LifecycleModule.java | 1 - .../java/io/druid/guice/LifecycleScope.java | 1 - .../java/io/druid/guice/ManageLifecycle.java | 2 + .../io/druid/guice/ManageLifecycleLast.java | 2 + .../main/java/io/druid/guice/PolyBind.java | 2 + .../guice/annotations/ExtensionPoint.java | 51 +++++++++++++++++++ .../io/druid/guice/annotations/Global.java | 1 + .../guice/annotations/JSR311Resource.java | 1 + .../java/io/druid/guice/annotations/Json.java | 1 + .../io/druid/guice/annotations/PublicApi.java | 49 ++++++++++++++++++ .../java/io/druid/guice/annotations/Self.java | 1 + .../io/druid/guice/annotations/Smile.java | 1 + .../io/druid/initialization/DruidModule.java | 2 + .../java/io/druid/js/JavaScriptConfig.java | 6 +++ .../java/io/druid/segment/SegmentUtils.java | 3 ++ .../segment/loading/DataSegmentArchiver.java | 2 + .../segment/loading/DataSegmentFinder.java | 2 + .../segment/loading/DataSegmentKiller.java | 2 + .../segment/loading/DataSegmentMover.java | 2 + .../segment/loading/DataSegmentPuller.java | 2 + .../segment/loading/DataSegmentPusher.java | 2 + .../io/druid/segment/loading/LoadSpec.java | 2 + .../loading/SegmentLoadingException.java | 3 ++ .../druid/segment/loading/URIDataPuller.java | 2 + .../java/io/druid/tasklogs/NoopTaskLogs.java | 1 - .../java/io/druid/tasklogs/TaskLogKiller.java | 3 ++ .../java/io/druid/tasklogs/TaskLogPusher.java | 3 ++ .../io/druid/tasklogs/TaskLogStreamer.java | 2 + .../main/java/io/druid/tasklogs/TaskLogs.java | 3 ++ .../java/io/druid/timeline/DataSegment.java | 2 + .../io/druid/timeline/DataSegmentUtils.java | 4 +- .../druid/timeline/partition/ShardSpec.java | 3 +- .../java/io/druid/utils/CompressionUtils.java | 6 ++- .../main/java/io/druid/utils/Runnables.java | 11 ++-- .../io/druid/data/input/MapBasedRowTest.java | 3 +- .../impl/JSONLowercaseParseSpecTest.java | 1 - .../data/input/impl/JSONParseSpecTest.java | 10 ++-- .../druid/data/input/impl/ParseSpecTest.java | 2 - .../io/druid/timeline/LogicalSegment.java | 2 + .../java/util/common/guava/Sequences.java | 1 + .../main/java/io/druid/query/BaseQuery.java | 2 + .../io/druid/query/BySegmentResultValue.java | 2 + .../java/io/druid/query/CacheStrategy.java | 2 + .../query/GenericQueryMetricsFactory.java | 6 +++ .../IntervalChunkingQueryRunnerDecorator.java | 2 + .../src/main/java/io/druid/query/Queries.java | 2 + .../src/main/java/io/druid/query/Query.java | 2 + .../java/io/druid/query/QueryContexts.java | 2 + .../java/io/druid/query/QueryMetrics.java | 3 ++ .../main/java/io/druid/query/QueryPlus.java | 2 + .../main/java/io/druid/query/QueryRunner.java | 2 + .../io/druid/query/QueryRunnerFactory.java | 2 + .../java/io/druid/query/QueryToolChest.java | 6 +-- .../src/main/java/io/druid/query/Result.java | 2 + .../ResultGranularTimestampComparator.java | 2 + .../druid/query/ResultMergeQueryRunner.java | 2 + .../druid/query/aggregation/Aggregator.java | 3 ++ .../query/aggregation/AggregatorFactory.java | 2 + .../query/aggregation/AggregatorUtil.java | 2 + .../query/aggregation/BufferAggregator.java | 2 + .../aggregation/MetricManipulationFn.java | 3 ++ .../query/aggregation/PostAggregator.java | 2 + .../io/druid/query/cache/CacheKeyBuilder.java | 2 + .../druid/query/dimension/DimensionSpec.java | 2 + .../segment/GenericColumnSerializer.java | 2 + .../main/java/io/druid/segment/Metadata.java | 2 + .../java/io/druid/segment/QueryableIndex.java | 5 ++ .../segment/QueryableIndexStorageAdapter.java | 6 --- .../main/java/io/druid/segment/Segment.java | 2 + .../java/io/druid/segment/StorageAdapter.java | 4 +- .../java/io/druid/segment/data/Indexed.java | 2 + .../io/druid/segment/data/ObjectStrategy.java | 3 ++ .../IncrementalIndexStorageAdapter.java | 6 --- .../serde/ComplexColumnSerializer.java | 2 + .../segment/serde/ComplexMetricExtractor.java | 2 + .../segment/serde/ComplexMetricSerde.java | 2 + ...olumnSupportedComplexColumnSerializer.java | 2 + 104 files changed, 308 insertions(+), 82 deletions(-) create mode 100644 api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java create mode 100644 api/src/main/java/io/druid/guice/annotations/PublicApi.java 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 69ead44276da..03df3b5becfe 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..182b31cda991 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.PublicApi; + 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 +@PublicApi +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 61fe512e2fc8..06d6b3ce85a8 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 org.joda.time.DateTime; import java.util.List; @@ -26,6 +27,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 534c5eec9290..1b77f1bb6a14 100644 --- a/api/src/main/java/io/druid/data/input/MapBasedRow.java +++ b/api/src/main/java/io/druid/data/input/MapBasedRow.java @@ -23,10 +23,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Function; import com.google.common.collect.Lists; - +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.logger.Logger; import io.druid.java.util.common.parsers.ParseException; - import org.joda.time.DateTime; import java.util.Collections; @@ -36,6 +35,7 @@ /** */ +@PublicApi public class MapBasedRow implements Row { private static final Logger log = new Logger(MapBasedRow.class); 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 2c3daa2afba4..3cc00a34b2fb 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/DimensionsSpec.java b/api/src/main/java/io/druid/data/input/impl/DimensionsSpec.java index 3028a7260b73..ad2184e7077f 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,6 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; - import io.druid.java.util.common.parsers.ParserUtils; import javax.annotation.Nullable; 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 c9850bebde99..69fe1e428245 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/MapInputRowParser.java b/api/src/main/java/io/druid/data/input/impl/MapInputRowParser.java index 8847dea0278e..1fafa37a6241 100644 --- a/api/src/main/java/io/druid/data/input/impl/MapInputRowParser.java +++ b/api/src/main/java/io/druid/data/input/impl/MapInputRowParser.java @@ -23,11 +23,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.Lists; import com.google.common.collect.Sets; - import io.druid.data.input.InputRow; import io.druid.data.input.MapBasedInputRow; import io.druid.java.util.common.parsers.ParseException; - import org.joda.time.DateTime; import java.util.List; 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..7c319e2c1f2f 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,12 +22,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; - import io.druid.java.util.common.parsers.Parser; import java.util.List; /** + * Not an {@code ExtensionPoint} since extension parsers are meant to extend {@code InputRowParser}. */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "format", defaultImpl = DelimitedParseSpec.class) @JsonSubTypes(value = { 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/StringInputRowParser.java b/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java index a640ef10ac41..7637cb9b2774 100644 --- a/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java +++ b/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java @@ -24,6 +24,7 @@ import com.google.common.base.Charsets; import io.druid.data.input.ByteBufferInputRowParser; import io.druid.data.input.InputRow; +import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.parsers.ParseException; import io.druid.java.util.common.parsers.Parser; @@ -37,6 +38,7 @@ /** */ +@PublicApi public class StringInputRowParser implements ByteBufferInputRowParser { private static final Charset DEFAULT_CHARSET = Charsets.UTF_8; 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 5ebf8504e63c..83b67584ae2c 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,9 +22,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Function; - import io.druid.java.util.common.parsers.TimestampParser; - import org.joda.time.DateTime; import java.util.List; 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 f9017af2ff9f..28203341dbd6 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 eb65d7c2e284..ddfcc359fe71 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 95269baa95b5..2370e0292de3 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 4256467d7f6f..52a2419fb350 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 e542ad10c5e6..2ee86b0774b2 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 a76decabc38b..0d0e5bad59ed 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 javax.annotation.Nullable; import java.lang.reflect.ParameterizedType; @@ -44,6 +45,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..bd8ccac2dddd --- /dev/null +++ b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.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 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 fields, methods, or constructors. + * + * 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. + * + * Interfaces and classes not annotated with {@code @ExtensionPoint} or {@link PublicApi} may be modified or removed + * in any Druid release. 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, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) +@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..486349f7240b --- /dev/null +++ b/api/src/main/java/io/druid/guice/annotations/PublicApi.java @@ -0,0 +1,49 @@ +/* + * 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. + * + * 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 88a28095f438..5693538fd2b0 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 java.io.File; import java.io.FileInputStream; @@ -28,7 +29,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 9638ed48b15c..6dc3d39cf95b 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.timeline.DataSegment; import java.io.File; @@ -27,6 +28,7 @@ import java.net.URI; 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 3adef9c4513d..877e9b2c8747 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 061375c9c189..599212cc8b48 100644 --- a/api/src/main/java/io/druid/segment/loading/SegmentLoadingException.java +++ b/api/src/main/java/io/druid/segment/loading/SegmentLoadingException.java @@ -19,8 +19,11 @@ package io.druid.segment.loading; +import io.druid.guice.annotations.PublicApi; + /** */ +@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 aa110d11d026..2d1f1f2c5f2d 100644 --- a/api/src/main/java/io/druid/timeline/DataSegmentUtils.java +++ b/api/src/main/java/io/druid/timeline/DataSegmentUtils.java @@ -20,10 +20,9 @@ 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.logger.Logger; - import org.joda.time.DateTime; import org.joda.time.Interval; import org.joda.time.format.DateTimeFormatter; @@ -34,6 +33,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 a70ff66de484..883aae65b8c4 100644 --- a/api/src/main/java/io/druid/utils/Runnables.java +++ b/api/src/main/java/io/druid/utils/Runnables.java @@ -19,14 +19,15 @@ package io.druid.utils; +import io.druid.guice.annotations.PublicApi; + /** */ +@PublicApi public class Runnables { - public static Runnable getNoopRunnable(){ - return new Runnable(){ - @Override - public void run(){} - }; + public static Runnable getNoopRunnable() + { + return () -> {}; } } 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 d3192abf2014..b3d87cfef0c5 100644 --- a/api/src/test/java/io/druid/data/input/MapBasedRowTest.java +++ b/api/src/test/java/io/druid/data/input/MapBasedRowTest.java @@ -19,12 +19,11 @@ package io.druid.data.input; +import com.google.common.collect.ImmutableMap; import org.joda.time.DateTime; import org.junit.Assert; import org.junit.Test; -import com.google.common.collect.ImmutableMap; - public class MapBasedRowTest { @Test 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/JSONParseSpecTest.java b/api/src/test/java/io/druid/data/input/impl/JSONParseSpecTest.java index 3407496cd9ca..3aa3806c84ed 100644 --- a/api/src/test/java/io/druid/data/input/impl/JSONParseSpecTest.java +++ b/api/src/test/java/io/druid/data/input/impl/JSONParseSpecTest.java @@ -19,18 +19,16 @@ package io.druid.data.input.impl; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; import io.druid.TestObjectMapper; +import org.junit.Assert; +import org.junit.Test; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; -import org.junit.Assert; -import org.junit.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableList; - public class JSONParseSpecTest { private final ObjectMapper jsonMapper = new TestObjectMapper(); 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/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/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java b/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java index c132ce99d2c2..b9f3c8c02d82 100644 --- a/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java +++ b/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java @@ -23,6 +23,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Lists; +import com.oracle.jrockit.jfr.UseConstantPool; import java.io.Closeable; import java.util.Arrays; diff --git a/processing/src/main/java/io/druid/query/BaseQuery.java b/processing/src/main/java/io/druid/query/BaseQuery.java index 4a3e4716a592..190837fa6ab8 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.java.util.common.guava.Sequence; import io.druid.query.spec.QuerySegmentSpec; import org.joda.time.Duration; @@ -34,6 +35,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 a8ec5006d055..dc8d1f8f5ead 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 956293c7a6ea..baa6575e6451 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; @@ -33,6 +34,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 4e6745ca6d43..6c87b45330e2 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.java.util.common.guava.Sequence; import io.druid.query.datasourcemetadata.DataSourceMetadataQuery; import io.druid.query.filter.DimFilter; @@ -39,6 +40,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 f6453068bd82..f2fe284493b3 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 a7e17f43d242..bd1c67c9bab6 100644 --- a/processing/src/main/java/io/druid/query/QueryRunner.java +++ b/processing/src/main/java/io/druid/query/QueryRunner.java @@ -19,6 +19,7 @@ package io.druid.query; +import io.druid.guice.annotations.ExtensionPoint; import io.druid.java.util.common.guava.Sequence; import java.util.Map; @@ -28,6 +29,7 @@ * is the new one. Their default implementations delegate to each other. Every implementation of QueryRunner should * override only one of those methods. New implementations should override the new method: {@link #run(QueryPlus, 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 daabdfcf18e3..c889f4caf1f1 100644 --- a/processing/src/main/java/io/druid/query/QueryToolChest.java +++ b/processing/src/main/java/io/druid/query/QueryToolChest.java @@ -21,16 +21,16 @@ 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; 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 ba172938a97e..f9dd656b74c3 100644 --- a/processing/src/main/java/io/druid/query/Result.java +++ b/processing/src/main/java/io/druid/query/Result.java @@ -21,10 +21,12 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import io.druid.guice.annotations.PublicApi; import org.joda.time.DateTime; /** */ +@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 c42e9ad6a44a..a29bf5cfb42e 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 e160cbf75b59..3ae753d4abee 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 2eb34645f90b..aef3b7567e47 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; /** @@ -34,6 +36,7 @@ * * This interface is old and going away. It is being replaced by BufferAggregator */ +@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 ec15c68acb8b..6f113b5eba41 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.logger.Logger; import io.druid.segment.ColumnSelectorFactory; @@ -38,6 +39,7 @@ * provided to the Aggregator through the MetricSelector object, so whatever creates that object gets to choose how * the data is actually stored and accessed. */ +@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 fb6c9e274ac9..c308b056a222 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; @@ -33,6 +34,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 c45582e9e02d..fa00216aa0b6 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/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 3163569c0970..c8543a83018f 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 52a5b3c17656..7c3ed060321b 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 fac3004b6e0c..c6ae5ecae360 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndexStorageAdapter.java @@ -171,12 +171,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..7f71133f48e0 100644 --- a/processing/src/main/java/io/druid/segment/StorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/StorageAdapter.java @@ -19,6 +19,7 @@ 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; @@ -29,6 +30,7 @@ /** */ +@PublicApi public interface StorageAdapter extends CursorFactory { public String getSegmentIdentifier(); @@ -63,8 +65,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 3a19b4797bf1..a6d55a329f1b 100644 --- a/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/incremental/IncrementalIndexStorageAdapter.java @@ -170,12 +170,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 b31416d1b3f5..f7c0f418aa97 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.io.smoosh.FileSmoosher; import io.druid.segment.GenericColumnSerializer; import io.druid.segment.data.GenericIndexedWriter; @@ -45,6 +46,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 7c45b62c22be..fe3d2622a886 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.io.smoosh.FileSmoosher; import io.druid.segment.GenericColumnSerializer; import io.druid.segment.data.GenericIndexedWriter; @@ -57,6 +58,7 @@ public LargeColumnSupportedComplexColumnSerializer( this.columnSize = columnSize; } + @PublicApi public static LargeColumnSupportedComplexColumnSerializer create( IOPeon ioPeon, String filenameBase, From 3fbf4bd8f1da953a49b191a9cebb364c1d70c0d2 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Wed, 21 Jun 2017 08:17:15 -0700 Subject: [PATCH 2/9] Clean up wording. --- .../java/io/druid/guice/annotations/ExtensionPoint.java | 7 +++---- .../main/java/io/druid/guice/annotations/PublicApi.java | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java index bd8ccac2dddd..6c6ae3f8ac30 100644 --- a/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java +++ b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java @@ -28,15 +28,14 @@ * Signifies that the annotated entity 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 fields, methods, or constructors. + * 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. * - * Interfaces and classes not annotated with {@code @ExtensionPoint} or {@link PublicApi} may be modified or removed - * in any Druid release. Extension points are all considered public APIs in the sense of {@link PublicApi}, even if - * not explicitly annotated as such. + * 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 diff --git a/api/src/main/java/io/druid/guice/annotations/PublicApi.java b/api/src/main/java/io/druid/guice/annotations/PublicApi.java index 486349f7240b..f398dfe81a2d 100644 --- a/api/src/main/java/io/druid/guice/annotations/PublicApi.java +++ b/api/src/main/java/io/druid/guice/annotations/PublicApi.java @@ -31,6 +31,8 @@ * * 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 From bea326bcf7e96d7f63d430ac59bd9120fb20a9fd Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Wed, 21 Jun 2017 08:18:00 -0700 Subject: [PATCH 3/9] Remove unused import. --- .../src/main/java/io/druid/java/util/common/guava/Sequences.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java b/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java index b9f3c8c02d82..c132ce99d2c2 100644 --- a/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java +++ b/java-util/src/main/java/io/druid/java/util/common/guava/Sequences.java @@ -23,7 +23,6 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Lists; -import com.oracle.jrockit.jfr.UseConstantPool; import java.io.Closeable; import java.util.Arrays; From 100ca4d5956bff611f8f21fbe9ac5b62831701a9 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Wed, 21 Jun 2017 20:26:00 -0700 Subject: [PATCH 4/9] Remove unused imports. --- processing/src/main/java/io/druid/segment/StorageAdapter.java | 1 - .../segment/incremental/IncrementalIndexStorageAdapter.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/processing/src/main/java/io/druid/segment/StorageAdapter.java b/processing/src/main/java/io/druid/segment/StorageAdapter.java index 7f71133f48e0..62e3dfa250d2 100644 --- a/processing/src/main/java/io/druid/segment/StorageAdapter.java +++ b/processing/src/main/java/io/druid/segment/StorageAdapter.java @@ -26,7 +26,6 @@ import org.joda.time.Interval; import javax.annotation.Nullable; -import java.util.Map; /** */ 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 a6d55a329f1b..71891795bf08 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.FloatColumnSelector; @@ -61,7 +60,6 @@ import javax.annotation.Nullable; import java.util.Iterator; -import java.util.Map; /** */ From eed9e1f8d2827cadb258e19a3d34a40ba7a7bd72 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Wed, 5 Jul 2017 08:33:23 -0700 Subject: [PATCH 5/9] Only types can be extension points. --- .../main/java/io/druid/guice/annotations/ExtensionPoint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java index 6c6ae3f8ac30..9dc02e170442 100644 --- a/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java +++ b/api/src/main/java/io/druid/guice/annotations/ExtensionPoint.java @@ -25,7 +25,7 @@ import java.lang.annotation.Target; /** - * Signifies that the annotated entity is an extension point. Extension points are interfaces or non-final classes that + * 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. @@ -43,7 +43,7 @@ * * @see PublicApi */ -@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) +@Target({ElementType.TYPE}) @Retention(RetentionPolicy.SOURCE) public @interface ExtensionPoint { From 9a300b2423c04d9d9a5607c62698af281cacc5ef Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Tue, 25 Jul 2017 11:26:45 -0700 Subject: [PATCH 6/9] Adjust annotations some more. --- .../main/java/io/druid/data/input/impl/DimensionSchema.java | 2 ++ .../main/java/io/druid/data/input/impl/DimensionsSpec.java | 3 ++- api/src/main/java/io/druid/data/input/impl/ParseSpec.java | 5 ++--- .../java/io/druid/data/input/impl/StringInputRowParser.java | 1 - .../main/java/io/druid/data/input/impl/TimestampSpec.java | 2 ++ 5 files changed, 8 insertions(+), 5 deletions(-) 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 ad2184e7077f..ebd9f74e592f 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,6 +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; @@ -36,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/ParseSpec.java b/api/src/main/java/io/druid/data/input/impl/ParseSpec.java index 7c319e2c1f2f..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; -/** - * Not an {@code ExtensionPoint} since extension parsers are meant to extend {@code InputRowParser}. - */ +@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/StringInputRowParser.java b/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java index 7637cb9b2774..f5a99bc96119 100644 --- a/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java +++ b/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java @@ -38,7 +38,6 @@ /** */ -@PublicApi public class StringInputRowParser implements ByteBufferInputRowParser { private static final Charset DEFAULT_CHARSET = Charsets.UTF_8; 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 From be8fde6f0fb6f428760e749d0324695b1ab0fd76 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Tue, 25 Jul 2017 12:37:30 -0700 Subject: [PATCH 7/9] Remove unused import. --- .../main/java/io/druid/data/input/impl/StringInputRowParser.java | 1 - 1 file changed, 1 deletion(-) diff --git a/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java b/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java index f5a99bc96119..a640ef10ac41 100644 --- a/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java +++ b/api/src/main/java/io/druid/data/input/impl/StringInputRowParser.java @@ -24,7 +24,6 @@ import com.google.common.base.Charsets; import io.druid.data.input.ByteBufferInputRowParser; import io.druid.data.input.InputRow; -import io.druid.guice.annotations.PublicApi; import io.druid.java.util.common.parsers.ParseException; import io.druid.java.util.common.parsers.Parser; From 4aa3045d0be384f28f2021ab8003402eb11b88a8 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Thu, 27 Jul 2017 16:37:47 -0700 Subject: [PATCH 8/9] Make ServletFilterHolder an extension point. --- .../druid/server/initialization/jetty/ServletFilterHolder.java | 3 +++ 1 file changed, 3 insertions(+) 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 6a22f2303e3b..67e9dc5938b5 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 { From 3878d1aa6256e76d293921d0a68a6753b7fdd773 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Fri, 28 Jul 2017 10:16:20 -0700 Subject: [PATCH 9/9] Add a couple extension points, and update docs. --- .../java/io/druid/data/input/InputRow.java | 4 ++-- .../io/druid/metadata/PasswordProvider.java | 2 ++ docs/content/development/modules.md | 21 +++++++++++++------ .../druid/query/extraction/ExtractionFn.java | 2 ++ 4 files changed, 21 insertions(+), 8 deletions(-) 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 182b31cda991..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,7 +19,7 @@ package io.druid.data.input; -import io.druid.guice.annotations.PublicApi; +import io.druid.guice.annotations.ExtensionPoint; import java.util.List; @@ -30,7 +30,7 @@ * implement "schema-less" data ingestion that allows the system to add new dimensions as they appear. * */ -@PublicApi +@ExtensionPoint public interface InputRow extends Row { /** 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/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/extraction/ExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java index 3a8820a4e5b9..f4d3429665a3 100644 --- a/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java @@ -21,11 +21,13 @@ 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; /** */ +@ExtensionPoint @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes(value = { @JsonSubTypes.Type(name = "time", value = TimeDimExtractionFn.class),