Skip to content

Commit ce08a38

Browse files
committed
Lenient parsing for GroupConfig
1 parent 4466a1b commit ce08a38

File tree

2 files changed

+57
-4
lines changed
  • client/rest-high-level/src

2 files changed

+57
-4
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/transforms/pivot/GroupConfig.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,23 @@ public class GroupConfig implements ToXContentObject {
3636

3737
private final Map<String, SingleGroupSource> groups;
3838

39+
/**
40+
* Leniently parse a {@code GroupConfig}.
41+
* Parsing is lenient in that unknown fields in the root of the
42+
* object are ignored. Unknown group types {@link SingleGroupSource.Type}
43+
* will cause a parsing error.
44+
*
45+
* @param parser The XContent parser
46+
* @return The parsed object
47+
* @throws IOException On parsing error
48+
*/
3949
public static GroupConfig fromXContent(final XContentParser parser) throws IOException {
4050
LinkedHashMap<String, SingleGroupSource> groups = new LinkedHashMap<>();
4151

4252
// be parsing friendly, whether the token needs to be advanced or not (similar to what ObjectParser does)
4353
XContentParser.Token token;
4454
if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
45-
token = parser.currentToken();
55+
parser.currentToken();
4656
} else {
4757
token = parser.nextToken();
4858
if (token != XContentParser.Token.START_OBJECT) {
@@ -52,8 +62,16 @@ public static GroupConfig fromXContent(final XContentParser parser) throws IOExc
5262

5363
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
5464
ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
55-
String destinationFieldName = parser.currentName();
5665
token = parser.nextToken();
66+
if (token != XContentParser.Token.START_OBJECT) {
67+
// leniently skip over key-value and array fields in the root of the object
68+
if (token == XContentParser.Token.START_ARRAY) {
69+
parser.skipChildren();
70+
}
71+
continue;
72+
}
73+
String destinationFieldName = parser.currentName();
74+
5775
ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
5876
token = parser.nextToken();
5977
ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
@@ -75,7 +93,7 @@ public static GroupConfig fromXContent(final XContentParser parser) throws IOExc
7593
default:
7694
throw new ParsingException(parser.getTokenLocation(), "invalid grouping type: " + groupType);
7795
}
78-
96+
// destination field end_object
7997
parser.nextToken();
8098

8199
groups.put(destinationFieldName, groupSource);

client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/transforms/pivot/GroupConfigTests.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919

2020
package org.elasticsearch.client.dataframe.transforms.pivot;
2121

22+
import org.elasticsearch.common.bytes.BytesArray;
23+
import org.elasticsearch.common.xcontent.DeprecationHandler;
24+
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
2225
import org.elasticsearch.common.xcontent.XContentParser;
26+
import org.elasticsearch.common.xcontent.json.JsonXContent;
2327
import org.elasticsearch.test.AbstractXContentTestCase;
2428

2529
import java.io.IOException;
@@ -28,14 +32,16 @@
2832
import java.util.Map;
2933
import java.util.Set;
3034

35+
import static org.hamcrest.Matchers.instanceOf;
36+
3137
public class GroupConfigTests extends AbstractXContentTestCase<GroupConfig> {
3238

3339
public static GroupConfig randomGroupConfig() {
3440
Map<String, SingleGroupSource> groups = new LinkedHashMap<>();
3541

3642
// ensure that the unlikely does not happen: 2 group_by's share the same name
3743
Set<String> names = new HashSet<>();
38-
for (int i = 0; i < randomIntBetween(1, 1); ++i) {
44+
for (int i = 0; i < randomIntBetween(1, 4); ++i) {
3945
String targetFieldName = randomAlphaOfLengthBetween(1, 20);
4046
if (names.add(targetFieldName)) {
4147
SingleGroupSource groupBy;
@@ -72,4 +78,33 @@ protected GroupConfig doParseInstance(XContentParser parser) throws IOException
7278
protected boolean supportsUnknownFields() {
7379
return false;
7480
}
81+
82+
public void testLenientParsing() throws IOException {
83+
BytesArray json = new BytesArray(
84+
"{ " +
85+
"\"unknown-field\":\"foo\", " +
86+
"\"destination-field\": {" +
87+
"\"terms\": {" +
88+
"\"field\": \"term-field\"" +
89+
"}" +
90+
"}," +
91+
"\"unknown-field-2\":\"bar\"," +
92+
"\"destination-field2\": {" +
93+
"\"terms\": {" +
94+
"\"field\": \"term-field2\"" +
95+
"}" +
96+
"}," +
97+
"\"array-field\" : [1.0, 2.0]" +
98+
"}");
99+
XContentParser parser = JsonXContent.jsonXContent
100+
.createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, json.streamInput());
101+
102+
GroupConfig gc = GroupConfig.fromXContent(parser);
103+
104+
assertEquals(gc.getGroups().size(), 2);
105+
assertTrue(gc.getGroups().containsKey("destination-field"));
106+
SingleGroupSource groupSource = gc.getGroups().get("destination-field");
107+
assertThat(groupSource, instanceOf(TermsGroupSource.class));
108+
assertEquals(groupSource.getField(), "term-field");
109+
}
75110
}

0 commit comments

Comments
 (0)