diff --git a/docs/changelog/124873.yaml b/docs/changelog/124873.yaml new file mode 100644 index 0000000000000..f78a892e1dfdb --- /dev/null +++ b/docs/changelog/124873.yaml @@ -0,0 +1,5 @@ +pr: 124873 +summary: Restore V8 REST compatibility around highlight `force_source` parameter +area: Highlighting +type: bug +issues: [] diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/AbstractHighlighterBuilder.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/AbstractHighlighterBuilder.java index 64b1d76f05122..317586cab93bb 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/AbstractHighlighterBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/highlight/AbstractHighlighterBuilder.java @@ -17,6 +17,7 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.Rewriteable; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder.BoundaryScannerType; @@ -64,6 +65,8 @@ public abstract class AbstractHighlighterBuilder restApiVersion == RestApiVersion.V_8); public static final ParseField PHRASE_LIMIT_FIELD = new ParseField("phrase_limit"); public static final ParseField OPTIONS_FIELD = new ParseField("options"); public static final ParseField HIGHLIGHT_QUERY_FIELD = new ParseField("highlight_query"); @@ -666,6 +669,7 @@ static > BiFunction {}, FORCE_SOURCE_FIELD); // force_source is ignored parser.declareInt(HB::phraseLimit, PHRASE_LIMIT_FIELD); parser.declareInt(HB::maxAnalyzedOffset, MAX_ANALYZED_OFFSET_FIELD); parser.declareObject(HB::options, (XContentParser p, Void c) -> { diff --git a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java index 1bcc89b68c141..bc4b4765e9d78 100644 --- a/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/fetch/subphase/highlight/HighlightBuilderTests.java @@ -18,6 +18,8 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.Maps; import org.elasticsearch.common.util.set.Sets; +import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.core.RestApiVersion; import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.IndexVersion; @@ -46,6 +48,7 @@ import org.elasticsearch.xcontent.XContentFactory; import org.elasticsearch.xcontent.XContentParseException; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.json.JsonXContent; import org.junit.AfterClass; @@ -607,6 +610,36 @@ public void testOrderSerialization() throws Exception { } } + public void testForceSourceRemovedInV9() throws IOException { + String highlightJson = """ + { "fields" : { }, "force_source" : true } + """; + + XContentParserConfiguration config = XContentParserConfiguration.EMPTY.withRegistry(xContentRegistry()) + .withDeprecationHandler(LoggingDeprecationHandler.INSTANCE) + .withRestApiVersion(RestApiVersion.V_9); + try (XContentParser parser = JsonXContent.jsonXContent.createParser(config, highlightJson)) { + XContentParseException xContentParseException = expectThrows( + XContentParseException.class, + () -> HighlightBuilder.fromXContent(parser) + ); + assertThat(xContentParseException.getMessage(), containsString("unknown field [force_source]")); + } + } + + public void testForceSourceV8Comp() throws IOException { + String highlightJson = """ + { "fields" : { }, "force_source" : true } + """; + XContentParserConfiguration config = XContentParserConfiguration.EMPTY.withRegistry(xContentRegistry()) + .withDeprecationHandler(LoggingDeprecationHandler.INSTANCE) + .withRestApiVersion(RestApiVersion.V_8); + try (XContentParser parser = JsonXContent.jsonXContent.createParser(config, highlightJson)) { + HighlightBuilder.fromXContent(parser); + assertWarnings("Deprecated field [force_source] used, this field is unused and will be removed entirely"); + } + } + protected static XContentBuilder toXContent(HighlightBuilder highlight, XContentType contentType) throws IOException { XContentBuilder builder = XContentFactory.contentBuilder(contentType); if (randomBoolean()) {