diff --git a/processing/src/main/java/org/apache/druid/data/input/impl/DimensionSchema.java b/processing/src/main/java/org/apache/druid/data/input/impl/DimensionSchema.java index 55a7872a2ce7..afc2a5feea10 100644 --- a/processing/src/main/java/org/apache/druid/data/input/impl/DimensionSchema.java +++ b/processing/src/main/java/org/apache/druid/data/input/impl/DimensionSchema.java @@ -25,9 +25,11 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.databind.annotation.JsonTypeResolver; import com.google.common.base.Strings; import org.apache.druid.guice.BuiltInTypesModule; import org.apache.druid.guice.annotations.PublicApi; +import org.apache.druid.jackson.StrictTypeIdResolver; import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.java.util.emitter.EmittingLogger; import org.apache.druid.segment.AutoTypeColumnSchema; @@ -44,9 +46,27 @@ import java.util.Objects; /** + * Defines the schema of a single dimension in a dataset. + *
+ * Includes metadata such as the dimension's name, type, and whether it + * can hold multiple values. Supports Jackson serialization/deserialization, + * including polymorphic types via {@code @JsonSubTypes}. + *
+ * + *+ * Example JSON: + *
{@code
+ * {
+ * "type": "string",
+ * "name": "country",
+ * "multiValue": false
+ * }
+ * }
+ *
*/
@PublicApi
-@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = StringDimensionSchema.class)
+@JsonTypeResolver(StrictTypeIdResolver.Builder.class)
+@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "type", defaultImpl = StringDimensionSchema.class)
@JsonSubTypes(value = {
@JsonSubTypes.Type(name = DimensionSchema.STRING_TYPE_NAME, value = StringDimensionSchema.class),
@JsonSubTypes.Type(name = DimensionSchema.LONG_TYPE_NAME, value = LongDimensionSchema.class),
diff --git a/processing/src/main/java/org/apache/druid/jackson/StrictTypeIdResolver.java b/processing/src/main/java/org/apache/druid/jackson/StrictTypeIdResolver.java
new file mode 100644
index 000000000000..e4b4d54ebf0d
--- /dev/null
+++ b/processing/src/main/java/org/apache/druid/jackson/StrictTypeIdResolver.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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 org.apache.druid.jackson;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DatabindContext;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.cfg.MapperConfig;
+import com.fasterxml.jackson.databind.jsontype.NamedType;
+import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
+import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
+import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
+import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
+import com.fasterxml.jackson.databind.jsontype.impl.TypeNameIdResolver;
+
+import java.util.Collection;
+
+/**
+ * A strict {@link TypeIdResolver} implementation that validates all incoming type ids.
+ * + * During deserialization, the type discriminator in the JSON must correspond to a registered subtype; + * otherwise this resolver will throw an exception instead of silently accepting or defaulting. + *
+ * An optional default implementation may still be configured and used only when the type id is absent.
+ */
+public class StrictTypeIdResolver extends TypeIdResolverBase
+{
+ public static class Builder extends StdTypeResolverBuilder
+ {
+ @Override
+ protected TypeIdResolver idResolver(
+ MapperConfig> config,
+ JavaType baseType,
+ PolymorphicTypeValidator subtypeValidator,
+ Collection