Fix AliasMetaData parsing (#30866)

AliasMetaData should be parsed more leniently so that the high-level REST client can support forward compatibility on it. This commit addresses this issue that was found as part of #28799 and adds dedicated XContent tests as well.
This commit is contained in:
olcbean 2018-05-30 12:31:24 +02:00 committed by Luca Cavanna
parent ff8ce2c575
commit 6341d101d2
2 changed files with 68 additions and 5 deletions

View File

@ -30,10 +30,12 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import java.io.IOException;
import java.util.Collections;
@ -42,7 +44,7 @@ import java.util.Set;
import static java.util.Collections.emptySet;
public class AliasMetaData extends AbstractDiffable<AliasMetaData> {
public class AliasMetaData extends AbstractDiffable<AliasMetaData> implements ToXContentFragment {
private final String alias;
@ -199,6 +201,17 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> {
return readDiffFrom(AliasMetaData::new, in);
}
@Override
public String toString() {
return Strings.toString(this, true, true);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
AliasMetaData.Builder.toXContent(this, builder, params);
return builder;
}
public static class Builder {
private final String alias;
@ -314,6 +327,8 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> {
if ("filter".equals(currentFieldName)) {
Map<String, Object> filter = parser.mapOrdered();
builder.filter(filter);
} else {
parser.skipChildren();
}
} else if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
if ("filter".equals(currentFieldName)) {
@ -327,6 +342,8 @@ public class AliasMetaData extends AbstractDiffable<AliasMetaData> {
} else if ("search_routing".equals(currentFieldName) || "searchRouting".equals(currentFieldName)) {
builder.searchRouting(parser.text());
}
} else if (token == XContentParser.Token.START_ARRAY) {
parser.skipChildren();
}
}
return builder.build();

View File

@ -19,18 +19,19 @@
package org.elasticsearch.cluster.metadata;
import org.elasticsearch.cluster.metadata.AliasMetaData.Builder;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractXContentTestCase;
import java.io.IOException;
import java.util.function.Predicate;
import static org.hamcrest.Matchers.equalTo;
public class AliasMetaDataTests extends ESTestCase {
public class AliasMetaDataTests extends AbstractXContentTestCase<AliasMetaData> {
public void testSerialization() throws IOException {
final AliasMetaData before =
@ -52,4 +53,49 @@ public class AliasMetaDataTests extends ESTestCase {
assertThat(after, equalTo(before));
}
@Override
protected AliasMetaData createTestInstance() {
return createTestItem();
}
@Override
protected Predicate<String> getRandomFieldsExcludeFilter() {
return p -> p.equals("") // do not add elements at the top-level as any element at this level is parsed as a new alias
|| p.contains(".filter"); // do not insert random data into AliasMetaData#filter
}
@Override
protected AliasMetaData doParseInstance(XContentParser parser) throws IOException {
if (parser.nextToken() == XContentParser.Token.START_OBJECT) {
parser.nextToken();
}
assertEquals(XContentParser.Token.FIELD_NAME, parser.currentToken());
AliasMetaData aliasMetaData = AliasMetaData.Builder.fromXContent(parser);
assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken());
return aliasMetaData;
}
@Override
protected boolean supportsUnknownFields() {
return true;
}
private static AliasMetaData createTestItem() {
Builder builder = AliasMetaData.builder(randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
builder.routing(randomAlphaOfLengthBetween(3, 10));
}
if (randomBoolean()) {
builder.searchRouting(randomAlphaOfLengthBetween(3, 10));
}
if (randomBoolean()) {
builder.indexRouting(randomAlphaOfLengthBetween(3, 10));
}
if (randomBoolean()) {
builder.filter("{\"term\":{\"year\":2016}}");
}
return builder.build();
}
}