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 extends T> 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 extends T> 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),