Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature flag for subobjects auto #114616

Merged
merged 8 commits into from
Oct 12, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public class CcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
.setting("xpack.security.enabled", "false")
// geohex_grid requires gold license
.setting("xpack.license.self_generated.type", "trial")
.feature(FeatureFlag.TIME_SERIES_MODE);
.feature(FeatureFlag.TIME_SERIES_MODE)
.feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED);

private static ElasticsearchCluster remoteCluster = ElasticsearchCluster.local()
.name(REMOTE_CLUSTER_NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public class RcsCcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
.setting("xpack.security.remote_cluster_server.ssl.enabled", "false")
.setting("xpack.security.remote_cluster_client.ssl.enabled", "false")
.feature(FeatureFlag.TIME_SERIES_MODE)
.feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.user("test_admin", "x-pack-test-password");

private static ElasticsearchCluster fulfillingCluster = ElasticsearchCluster.local()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class SmokeTestMultiNodeClientYamlTestSuiteIT extends ESClientYamlSuiteTe
// The first node does not have the ingest role so we're sure ingest requests are forwarded:
.node(0, n -> n.setting("node.roles", "[master,data,ml,remote_cluster_client,transform]"))
.feature(FeatureFlag.TIME_SERIES_MODE)
.feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.build();

public SmokeTestMultiNodeClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
.module("health-shards-availability")
.module("data-streams")
.feature(FeatureFlag.TIME_SERIES_MODE)
.feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.build();

public ClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.util.FeatureFlag;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.features.NodeFeature;
Expand All @@ -41,6 +42,7 @@

public class ObjectMapper extends Mapper {
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(ObjectMapper.class);
public static final FeatureFlag SUB_OBJECTS_AUTO_FEATURE_FLAG = new FeatureFlag("sub_objects_auto");

public static final String CONTENT_TYPE = "object";
static final String STORE_ARRAY_SOURCE_PARAM = "store_array_source";
Expand Down Expand Up @@ -74,7 +76,7 @@ public static Subobjects from(Object node) {
if (value.equalsIgnoreCase("false")) {
return DISABLED;
}
if (value.equalsIgnoreCase("auto")) {
if (SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled() && value.equalsIgnoreCase("auto")) {
return AUTO;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,7 @@ public void testSubobjectsFalseWithInnerNestedFromDynamicTemplate() {
}

public void testSubobjectsAutoFlatPaths() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createDynamicTemplateAutoSubobjects();
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.field("foo.metric.count", 10);
Expand All @@ -1389,6 +1390,7 @@ public void testSubobjectsAutoFlatPaths() throws IOException {
}

public void testSubobjectsAutoStructuredPaths() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createDynamicTemplateAutoSubobjects();
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.startObject("foo");
Expand All @@ -1411,6 +1413,7 @@ public void testSubobjectsAutoStructuredPaths() throws IOException {
}

public void testSubobjectsAutoArrayOfObjects() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createDynamicTemplateAutoSubobjects();
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.startObject("foo");
Expand Down Expand Up @@ -1444,6 +1447,7 @@ public void testSubobjectsAutoArrayOfObjects() throws IOException {
}

public void testSubobjectAutoDynamicNested() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.startArray("dynamic_templates");
{
Expand Down Expand Up @@ -1482,6 +1486,7 @@ public void testSubobjectAutoDynamicNested() throws IOException {
}

public void testRootSubobjectAutoDynamicNested() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.startArray("dynamic_templates");
{
Expand Down Expand Up @@ -1515,6 +1520,7 @@ public void testRootSubobjectAutoDynamicNested() throws IOException {
}

public void testDynamicSubobjectsAutoDynamicFalse() throws Exception {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
// verify that we read the dynamic value properly from the parent mapper. DocumentParser#dynamicOrDefault splits the field
// name where dots are found, but it does that only for the parent prefix e.g. metrics.service and not for the leaf suffix time.max
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
Expand Down Expand Up @@ -1578,6 +1584,7 @@ public void testDynamicSubobjectsAutoDynamicFalse() throws Exception {
}

public void testSubobjectsAutoWithInnerNestedFromDynamicTemplate() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.startArray("dynamic_templates");
{
Expand Down Expand Up @@ -2045,6 +2052,7 @@ public void testSubobjectsFalseFlattened() throws IOException {
}

public void testSubobjectsAutoFlattened() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
String mapping = """
{
"_doc": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,27 +169,29 @@ public void testMergeEnabledForIndexTemplates() throws IOException {
assertEquals(ObjectMapper.Subobjects.ENABLED, objectMapper.subobjects());
assertTrue(objectMapper.sourceKeepMode().isEmpty());

// Setting 'enabled' to true is allowed, and updates the mapping.
update = Strings.toString(
XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject("object")
.field("type", "object")
.field("enabled", true)
.field("subobjects", "auto")
.field(ObjectMapper.STORE_ARRAY_SOURCE_PARAM, true)
.endObject()
.endObject()
.endObject()
);
mapper = mapperService.merge("type", new CompressedXContent(update), MergeReason.INDEX_TEMPLATE);

objectMapper = mapper.mappers().objectMappers().get("object");
assertNotNull(objectMapper);
assertTrue(objectMapper.isEnabled());
assertEquals(ObjectMapper.Subobjects.AUTO, objectMapper.subobjects());
assertEquals(Mapper.SourceKeepMode.ARRAYS, objectMapper.sourceKeepMode().orElse(Mapper.SourceKeepMode.NONE));
if (ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled()) {
// Setting 'enabled' to true is allowed, and updates the mapping.
update = Strings.toString(
XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject("object")
.field("type", "object")
.field("enabled", true)
.field("subobjects", "auto")
.field(ObjectMapper.STORE_ARRAY_SOURCE_PARAM, true)
.endObject()
.endObject()
.endObject()
);
mapper = mapperService.merge("type", new CompressedXContent(update), MergeReason.INDEX_TEMPLATE);

objectMapper = mapper.mappers().objectMappers().get("object");
assertNotNull(objectMapper);
assertTrue(objectMapper.isEnabled());
assertEquals(ObjectMapper.Subobjects.AUTO, objectMapper.subobjects());
assertEquals(Mapper.SourceKeepMode.ARRAYS, objectMapper.sourceKeepMode().orElse(Mapper.SourceKeepMode.NONE));
}
}

public void testFieldReplacementForIndexTemplates() throws IOException {
Expand Down Expand Up @@ -503,6 +505,7 @@ public void testSubobjectsCannotBeUpdatedOnRoot() throws IOException {
}

public void testSubobjectsAuto() throws Exception {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("metrics.service");
{
Expand Down Expand Up @@ -532,6 +535,7 @@ public void testSubobjectsAuto() throws Exception {
}

public void testSubobjectsAutoWithInnerObject() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("metrics.service");
{
Expand Down Expand Up @@ -565,6 +569,7 @@ public void testSubobjectsAutoWithInnerObject() throws IOException {
}

public void testSubobjectsAutoWithInnerNested() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("metrics.service");
{
Expand All @@ -586,6 +591,7 @@ public void testSubobjectsAutoWithInnerNested() throws IOException {
}

public void testSubobjectsAutoRoot() throws Exception {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mappingWithSubobjects(b -> {
b.startObject("metrics.service.time");
b.field("type", "long");
Expand All @@ -606,6 +612,7 @@ public void testSubobjectsAutoRoot() throws Exception {
}

public void testSubobjectsAutoRootWithInnerObject() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mappingWithSubobjects(b -> {
b.startObject("metrics.service.time");
{
Expand All @@ -626,6 +633,7 @@ public void testSubobjectsAutoRootWithInnerObject() throws IOException {
}

public void testSubobjectsAutoRootWithInnerNested() throws IOException {
assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mappingWithSubobjects(b -> {
b.startObject("metrics.service");
b.field("type", "nested");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
public enum FeatureFlag {
TIME_SERIES_MODE("es.index_mode_feature_flag_registered=true", Version.fromString("8.0.0"), null),
FAILURE_STORE_ENABLED("es.failure_store_feature_flag_enabled=true", Version.fromString("8.12.0"), null),
SUB_OBJECTS_AUTO_ENABLED("es.sub_objects_auto_feature_flag_enabled=true", Version.fromString("8.16.0"), null),
CHUNKING_SETTINGS_ENABLED("es.inference_chunking_settings_feature_flag_enabled=true", Version.fromString("8.16.0"), null),
INFERENCE_DEFAULT_ELSER("es.inference_default_elser_feature_flag_enabled=true", Version.fromString("8.16.0"), null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class XPackRestIT extends AbstractXPackRestTest {
.setting("xpack.searchable.snapshot.shared_cache.region_size", "256KB")
.user("x_pack_rest_user", "x-pack-test-password")
.feature(FeatureFlag.TIME_SERIES_MODE)
.feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.configFile("testnode.pem", Resource.fromClasspath("org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"))
.configFile("testnode.crt", Resource.fromClasspath("org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.configFile("service_tokens", Resource.fromClasspath("service_tokens"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class CoreWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTest
.setting("xpack.security.autoconfiguration.enabled", "false")
.user(USER, PASS)
.feature(FeatureFlag.TIME_SERIES_MODE)
.feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.build();

public CoreWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
Expand Down
1 change: 1 addition & 0 deletions x-pack/qa/runtime-fields/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ subprojects {
setting 'xpack.security.enabled', 'false'

requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
requiresFeature 'es.sub_objects_auto_feature_flag_enabled', Version.fromString("8.16.0")
}

tasks.named("yamlRestTest").configure {
Expand Down