Skip to content

Commit 62d4452

Browse files
author
Christoph Büscher
authored
Fix varying responses for <index>/_analyze request (#44342)
Currently we loose information about whether a token list in an AnalyzeAction response is null or an empty list, because we write a 0 value to the stream in both cases and deserialize to a null value on the receiving side. This was fixed in #44284 by a change in the serialization protocol starting in 7.3. However this PR fixes the symptoms without changing the wire protocol which we cannot to easily on 6.8 because we already released incompatible versions in the 7.x line. This change adds special handling on xcontent output and if getToken() is callled on either AnalyzeResponse or DetailedAnalyzeResponse to always return empty lists instead of null values. Relates to #44078
1 parent 79ea611 commit 62d4452

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/IndicesClientDocumentationIT.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@
7070
import org.elasticsearch.client.indices.GetIndexRequest;
7171
import org.elasticsearch.client.indices.GetIndexResponse;
7272
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
73+
import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
7374
import org.elasticsearch.client.indices.GetMappingsRequest;
7475
import org.elasticsearch.client.indices.GetMappingsResponse;
75-
import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
7676
import org.elasticsearch.client.indices.IndexTemplateMetaData;
7777
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
7878
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
@@ -2083,7 +2083,7 @@ public void testPutTemplate() throws Exception {
20832083
" \"type\": \"text\"\n" +
20842084
" }\n" +
20852085
" }\n" +
2086-
"}",
2086+
"}",
20872087
XContentType.JSON);
20882088
// end::put-template-request-mappings-json
20892089
assertTrue(client.indices().putTemplate(request, RequestOptions.DEFAULT).isAcknowledged());
@@ -2098,7 +2098,7 @@ public void testPutTemplate() throws Exception {
20982098
message.put("type", "text");
20992099
properties.put("message", message);
21002100
}
2101-
jsonMap.put("properties", properties);
2101+
jsonMap.put("properties", properties);
21022102
}
21032103
request.mapping(jsonMap); // <1>
21042104
//end::put-template-request-mappings-map
@@ -2455,7 +2455,7 @@ public void testAnalyze() throws IOException, InterruptedException {
24552455
DetailAnalyzeResponse detail = response.detail(); // <1>
24562456
// end::analyze-response-detail
24572457

2458-
assertNull(tokens);
2458+
assertEquals(0, tokens.size());
24592459
assertNotNull(detail.tokenizer());
24602460
}
24612461

server/src/main/java/org/elasticsearch/action/admin/indices/analyze/AnalyzeResponse.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import java.io.IOException;
3434
import java.util.ArrayList;
35+
import java.util.Collections;
3536
import java.util.HashMap;
3637
import java.util.Iterator;
3738
import java.util.List;
@@ -233,7 +234,7 @@ public AnalyzeResponse(List<AnalyzeToken> tokens, DetailAnalyzeResponse detail)
233234
}
234235

235236
public List<AnalyzeToken> getTokens() {
236-
return this.tokens;
237+
return this.tokens != null ? this.tokens : Collections.emptyList();
237238
}
238239

239240
public DetailAnalyzeResponse detail() {
@@ -254,6 +255,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
254255
token.toXContent(builder, params);
255256
}
256257
builder.endArray();
258+
} else if (detail == null) {
259+
// at least write an empty list
260+
builder.startArray(Fields.TOKENS);
261+
builder.endArray();
257262
}
258263

259264
if (detail != null) {

server/src/main/java/org/elasticsearch/action/admin/indices/analyze/DetailAnalyzeResponse.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.elasticsearch.action.admin.indices.analyze;
2121

2222

23+
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse.AnalyzeToken;
2324
import org.elasticsearch.common.ParseField;
2425
import org.elasticsearch.common.Strings;
2526
import org.elasticsearch.common.io.stream.StreamInput;
@@ -284,7 +285,7 @@ public String getName() {
284285
}
285286

286287
public AnalyzeResponse.AnalyzeToken[] getTokens() {
287-
return tokens;
288+
return tokens != null ? tokens : new AnalyzeToken[0];
288289
}
289290

290291
public static AnalyzeTokenList readAnalyzeTokenList(StreamInput in) throws IOException {
@@ -296,8 +297,10 @@ public static AnalyzeTokenList readAnalyzeTokenList(StreamInput in) throws IOExc
296297
XContentBuilder toXContentWithoutObject(XContentBuilder builder, Params params) throws IOException {
297298
builder.field(Fields.NAME, this.name);
298299
builder.startArray(AnalyzeResponse.Fields.TOKENS);
299-
for (AnalyzeResponse.AnalyzeToken token : tokens) {
300-
token.toXContent(builder, params);
300+
if (tokens != null) {
301+
for (AnalyzeResponse.AnalyzeToken token : tokens) {
302+
token.toXContent(builder, params);
303+
}
301304
}
302305
builder.endArray();
303306
return builder;

server/src/test/java/org/elasticsearch/indices/analyze/AnalyzeActionIT.java

+20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.elasticsearch.action.admin.indices.alias.Alias;
2222
import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequestBuilder;
2323
import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
24+
import org.elasticsearch.common.Strings;
2425
import org.elasticsearch.common.settings.Settings;
2526
import org.elasticsearch.plugins.Plugin;
2627
import org.elasticsearch.test.ESIntegTestCase;
@@ -436,5 +437,24 @@ public void testAnalyzeNormalizedKeywordField() throws IOException {
436437
assertThat(token.getPositionLength(), equalTo(1));
437438
}
438439

440+
/**
441+
* Input text that doesn't produce tokens should return an empty token list
442+
*/
443+
public void testZeroTokenAnalysis() throws IOException {
444+
assertAcked(prepareCreate("test"));
445+
ensureGreen("test");
446+
447+
AnalyzeResponse analyzeResponse = client().admin().indices().prepareAnalyze("test", ".").get();
448+
assertNotNull(analyzeResponse.getTokens());
449+
assertThat(analyzeResponse.getTokens().size(), equalTo(0));
450+
assertEquals("{\"tokens\":[]}", Strings.toString(analyzeResponse));
451+
452+
// also check detailed response
453+
analyzeResponse = client().admin().indices().prepareAnalyze("test", ".").setExplain(true).get();
454+
assertNotNull(analyzeResponse.detail().analyzer().getTokens());
455+
assertThat(analyzeResponse.getTokens().size(), equalTo(0));
456+
assertEquals("{\"detail\":{\"custom_analyzer\":false,\"analyzer\":{\"name\":\"default\",\"tokens\":[]}}}",
457+
Strings.toString(analyzeResponse));
458+
}
439459

440460
}

0 commit comments

Comments
 (0)