in server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java [2631:2786]
public static IndexMetadata fromXContent(XContentParser parser, Map<String, MappingMetadata> mappingsByHash) throws IOException {
if (parser.currentToken() == null) { // fresh parser? move to the first token
parser.nextToken();
}
if (parser.currentToken() == XContentParser.Token.START_OBJECT) { // on a start object move to next token
parser.nextToken();
}
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser);
Builder builder = new Builder(parser.currentName());
// default to UNKNOWN so that reading 'event.ingested' range content works in older versions
builder.eventIngestedRange(IndexLongFieldRange.UNKNOWN);
String currentFieldName;
XContentParser.Token token = parser.nextToken();
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser);
boolean mappingVersion = false;
boolean settingsVersion = false;
boolean aliasesVersion = false;
while ((currentFieldName = parser.nextFieldName()) != null) {
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
switch (currentFieldName) {
case KEY_SETTINGS:
builder.settings(Settings.fromXContent(parser));
break;
case KEY_MAPPINGS:
while ((currentFieldName = parser.nextFieldName()) != null) {
token = parser.nextToken();
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser);
builder.putMapping(new MappingMetadata(currentFieldName, Map.of(currentFieldName, parser.mapOrdered())));
}
break;
case KEY_ALIASES:
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
builder.putAlias(AliasMetadata.Builder.fromXContent(parser));
}
break;
case KEY_IN_SYNC_ALLOCATIONS:
while ((currentFieldName = parser.nextFieldName()) != null) {
token = parser.nextToken();
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_ARRAY, token, parser);
final int shardId = Integer.parseInt(currentFieldName);
Set<String> allocationIds = new HashSet<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token == XContentParser.Token.VALUE_STRING) {
allocationIds.add(parser.text());
}
}
builder.putInSyncAllocationIds(shardId, allocationIds);
}
break;
case KEY_ROLLOVER_INFOS:
while ((currentFieldName = parser.nextFieldName()) != null) {
token = parser.nextToken();
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser);
builder.putRolloverInfo(RolloverInfo.parse(parser, currentFieldName));
}
break;
case "warmers":
// TODO: do this in 6.0:
// throw new IllegalArgumentException("Warmers are not supported anymore - are you upgrading from 1.x?");
// ignore: warmers have been removed in 5.0 and are
// simply ignored when upgrading from 2.x
assert Version.CURRENT.major <= 5;
parser.skipChildren();
break;
case KEY_TIMESTAMP_RANGE:
builder.timestampRange(IndexLongFieldRange.fromXContent(parser));
break;
case KEY_EVENT_INGESTED_RANGE:
builder.eventIngestedRange(IndexLongFieldRange.fromXContent(parser));
break;
case KEY_STATS:
builder.stats(IndexMetadataStats.fromXContent(parser));
break;
case KEY_INFERENCE_FIELDS:
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
builder.putInferenceField(InferenceFieldMetadata.fromXContent(parser));
}
break;
case KEY_RESHARDING:
builder.reshardingMetadata(IndexReshardingMetadata.fromXContent(parser));
break;
default:
// assume it's custom index metadata
builder.putCustom(currentFieldName, parser.mapStrings());
break;
}
} else if (token == XContentParser.Token.START_ARRAY) {
switch (currentFieldName) {
case KEY_MAPPINGS:
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
builder.putMapping(new MappingMetadata(new CompressedXContent(parser.binaryValue())));
} else {
Map<String, Object> mapping = parser.mapOrdered();
if (mapping.size() == 1) {
String mappingType = mapping.keySet().iterator().next();
builder.putMapping(new MappingMetadata(mappingType, mapping));
}
}
}
break;
case KEY_PRIMARY_TERMS:
ArrayList<Long> list = new ArrayList<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_NUMBER, token, parser);
list.add(parser.longValue());
}
builder.primaryTerms(list.stream().mapToLong(i -> i).toArray());
break;
default:
throw new IllegalArgumentException("Unexpected field for an array " + currentFieldName);
}
} else if (token.isValue()) {
switch (currentFieldName) {
case KEY_STATE -> builder.state(State.fromString(parser.text()));
case KEY_VERSION -> builder.version(parser.longValue());
case KEY_MAPPING_VERSION -> {
mappingVersion = true;
builder.mappingVersion(parser.longValue());
}
case KEY_SETTINGS_VERSION -> {
settingsVersion = true;
builder.settingsVersion(parser.longValue());
}
case KEY_ALIASES_VERSION -> {
aliasesVersion = true;
builder.aliasesVersion(parser.longValue());
}
case KEY_ROUTING_NUM_SHARDS -> builder.setRoutingNumShards(parser.intValue());
case KEY_SYSTEM -> builder.system(parser.booleanValue());
case KEY_MAPPINGS_HASH -> {
assert mappingsByHash != null : "no deduplicated mappings given";
if (mappingsByHash.containsKey(parser.text()) == false) {
throw new IllegalArgumentException(
"mapping of index [" + builder.index + "] with hash [" + parser.text() + "] not found"
);
}
builder.putMapping(mappingsByHash.get(parser.text()));
}
case KEY_MAPPINGS_UPDATED_VERSION -> builder.mappingsUpdatedVersion(IndexVersion.fromId(parser.intValue()));
case KEY_WRITE_LOAD_FORECAST -> builder.indexWriteLoadForecast(parser.doubleValue());
case KEY_SHARD_SIZE_FORECAST -> builder.shardSizeInBytesForecast(parser.longValue());
default -> throw new IllegalArgumentException("Unexpected field [" + currentFieldName + "]");
}
} else {
throw new IllegalArgumentException("Unexpected token " + token);
}
}
XContentParserUtils.ensureExpectedToken(XContentParser.Token.END_OBJECT, parser.nextToken(), parser);
assert mappingVersion : "mapping version should be present for indices created on or after 6.5.0";
assert settingsVersion : "settings version should be present for indices created on or after 6.5.0";
assert indexCreatedVersion(builder.settings).before(IndexVersions.V_7_2_0) || aliasesVersion
: "aliases version should be present for indices created on or after 7.2.0";
return builder.build(true);
}