Skip to content

Commit

Permalink
Convert most of the parsing logic over to object parsers.
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaiera committed Jun 26, 2018
1 parent c2a591d commit 104b723
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 229 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.support.broadcast.BroadcastShardResponse;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
Expand All @@ -34,6 +37,9 @@

import java.io.IOException;

import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;

public class SnapshotIndexShardStatus extends BroadcastShardResponse implements ToXContentFragment {

private SnapshotIndexShardStage stage = SnapshotIndexShardStage.INIT;
Expand Down Expand Up @@ -167,57 +173,50 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
return builder;
}

public static SnapshotIndexShardStatus fromXContent(XContentParser parser, String indexId) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
String shardName = parser.currentName();
int shard;
try {
shard = Integer.parseInt(shardName);
} catch (NumberFormatException nfe) {
throw new ElasticsearchParseException(
"failed to parse snapshot index shard status [{}], expected numeric shard id but got [{}]", indexId, shardName);
}
ShardId shardId = new ShardId(new Index(indexId, IndexMetaData.INDEX_UUID_NA_VALUE), shard);
XContentParser.Token token = parser.nextToken();
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
SnapshotIndexShardStage stage = null;
String nodeId = null;
String failure = null;
SnapshotStats stats = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token.equals(XContentParser.Token.FIELD_NAME)) {
String currentName = parser.currentName();
if (currentName.equals(Fields.STAGE)) {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_STRING, parser.nextToken(),
parser::getTokenLocation);
try {
stage = SnapshotIndexShardStage.valueOf(parser.text());
} catch (IllegalArgumentException iae) {
throw new ElasticsearchParseException(
"failed to parse snapshot index shard status [{}][{}], unknonwn stage [{}]", indexId, shardId.getId(),
parser.text());
}
} else if (currentName.equals(Fields.NODE)) {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_STRING, parser.nextToken(),
parser::getTokenLocation);
nodeId = parser.text();
} else if (currentName.equals(Fields.REASON)) {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.VALUE_STRING, parser.nextToken(),
parser::getTokenLocation);
failure = parser.text();
} else if (currentName.equals(SnapshotStats.Fields.STATS)) {
stats = SnapshotStats.fromXContent(parser);
} else {
static final ObjectParser.NamedObjectParser<SnapshotIndexShardStatus, String> PARSER;
static {
ConstructingObjectParser<SnapshotIndexShardStatus, ShardId> innerParser = new ConstructingObjectParser<>(
"snapshot_index_shard_status", false,
(Object[] parsedObjects, ShardId shard) -> {
int i = 0;
String rawStage = (String) parsedObjects[i++];
String nodeId = (String) parsedObjects[i++];
String failure = (String) parsedObjects[i++];
SnapshotStats stats = (SnapshotStats) parsedObjects[i];

SnapshotIndexShardStage stage;
try {
stage = SnapshotIndexShardStage.valueOf(rawStage);
} catch (IllegalArgumentException iae) {
throw new ElasticsearchParseException(
"failed to parse snapshot index shard status [{}][{}], unknown field [{}]", indexId, shardId.getId(),
currentName);
"failed to parse snapshot index shard status [{}][{}], unknonwn stage [{}]",
shard.getIndex().getName(), shard.getId(), rawStage);
}
} else {
return new SnapshotIndexShardStatus(shard, stage, stats, nodeId, failure);
}
);
innerParser.declareString(constructorArg(), new ParseField(Fields.STAGE));
innerParser.declareString(optionalConstructorArg(), new ParseField(Fields.NODE));
innerParser.declareString(optionalConstructorArg(), new ParseField(Fields.REASON));
innerParser.declareObject(constructorArg(), (p, c) -> SnapshotStats.fromXContent(p), new ParseField(SnapshotStats.Fields.STATS));
PARSER = (p, indexId, shardName) -> {
// Combine the index name in the context with the shard name passed in for the named object parser
// into a ShardId to pass as context for the inner parser.
int shard;
try {
shard = Integer.parseInt(shardName);
} catch (NumberFormatException nfe) {
throw new ElasticsearchParseException(
"failed to parse snapshot index shard status [{}][{}]", indexId, shardId.getId());
"failed to parse snapshot index shard status [{}], expected numeric shard id but got [{}]", indexId, shardName);
}
}
return new SnapshotIndexShardStatus(shardId, stage, stats, nodeId, failure);
ShardId shardId = new ShardId(new Index(indexId, IndexMetaData.INDEX_UUID_NA_VALUE), shard);
return innerParser.parse(p, shardId);
};
}

public static SnapshotIndexShardStatus fromXContent(XContentParser parser, String indexId) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
return PARSER.parse(parser, indexId, parser.currentName());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

package org.elasticsearch.action.admin.cluster.snapshots.status;

import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
Expand All @@ -29,9 +31,12 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static java.util.Collections.emptyMap;
import static java.util.Collections.unmodifiableMap;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;

/**
* Represents snapshot status of all shards in the index
Expand Down Expand Up @@ -118,37 +123,38 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
return builder;
}

public static SnapshotIndexStatus fromXContent(XContentParser parser) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
String indexName = parser.currentName();
XContentParser.Token token = parser.nextToken();
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
SnapshotShardsStats shardsStats = null;
SnapshotStats stats = null;
Map<Integer, SnapshotIndexShardStatus> shards = new HashMap<>();
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token.equals(XContentParser.Token.FIELD_NAME)) {
String currentName = parser.currentName();
if (currentName.equals(SnapshotShardsStats.Fields.SHARDS_STATS)) {
shardsStats = SnapshotShardsStats.fromXContent(parser);
} else if (currentName.equals(SnapshotStats.Fields.STATS)) {
stats = SnapshotStats.fromXContent(parser);
} else if (currentName.equals(Fields.SHARDS)) {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(),
parser::getTokenLocation);
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
SnapshotIndexShardStatus shardStatus = SnapshotIndexShardStatus.fromXContent(parser, indexName);
shards.put(shardStatus.getShardId().getId(), shardStatus);
}
static final ObjectParser.NamedObjectParser<SnapshotIndexStatus, Void> PARSER;
static {
ConstructingObjectParser<SnapshotIndexStatus, String> innerParser = new ConstructingObjectParser<>(
"snapshot_index_status", false,
(Object[] parsedObjects, String index) -> {
int i = 0;
SnapshotShardsStats shardsStats = ((SnapshotShardsStats) parsedObjects[i++]);
SnapshotStats stats = ((SnapshotStats) parsedObjects[i++]);
@SuppressWarnings("unchecked") List<SnapshotIndexShardStatus> shardStatuses = (List<SnapshotIndexShardStatus>) parsedObjects[i];

final Map<Integer, SnapshotIndexShardStatus> indexShards;
if (shardStatuses == null || shardStatuses.isEmpty()) {
indexShards = emptyMap();
} else {
throw new ElasticsearchParseException("failed to parse snapshot index status [{}], unknown field [{}]", indexName,
currentName);
indexShards = new HashMap<>(shardStatuses.size());
for (SnapshotIndexShardStatus shardStatus : shardStatuses) {
indexShards.put(shardStatus.getShardId().getId(), shardStatus);
}
}
} else {
throw new ElasticsearchParseException("failed to parse snapshot index status [{}]", indexName);
}
}
return new SnapshotIndexStatus(indexName, shards, shardsStats, stats);
return new SnapshotIndexStatus(index, indexShards, shardsStats, stats);
});
innerParser.declareObject(constructorArg(), (p, c) -> SnapshotShardsStats.PARSER.apply(p, null),
new ParseField(SnapshotShardsStats.Fields.SHARDS_STATS));
innerParser.declareObject(constructorArg(), (p, c) -> SnapshotStats.fromXContent(p),
new ParseField(SnapshotStats.Fields.STATS));
innerParser.declareNamedObjects(constructorArg(), SnapshotIndexShardStatus.PARSER, new ParseField(Fields.SHARDS));
PARSER = ((p, c, name) -> innerParser.apply(p, name));
}

public static SnapshotIndexStatus fromXContent(XContentParser parser) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
return PARSER.parse(parser, null, parser.currentName());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@

package org.elasticsearch.action.admin.cluster.snapshots.status;

import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParserUtils;

import java.io.IOException;
import java.util.Collection;

import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;

/**
* Status of a snapshot shards
*/
Expand Down Expand Up @@ -141,62 +143,30 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par
return builder;
}

public static SnapshotShardsStats fromXContent(XContentParser parser) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
XContentParser.Token token;
int initializingShards = 0;
int startedShards = 0;
int finalizingShards = 0;
int doneShards = 0;
int failedShards = 0;
int totalShards = 0;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
String currentName = parser.currentName();
if (currentName.equals(Fields.INITIALIZING)) {
if (parser.nextToken() != XContentParser.Token.VALUE_NUMBER) {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]",
currentName);
}
initializingShards = parser.intValue();
} else if (currentName.equals(Fields.STARTED)) {
if (parser.nextToken() != XContentParser.Token.VALUE_NUMBER) {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]",
currentName);
}
startedShards = parser.intValue();
} else if (currentName.equals(Fields.FINALIZING)) {
if (parser.nextToken() != XContentParser.Token.VALUE_NUMBER) {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]",
currentName);
}
finalizingShards = parser.intValue();
} else if (currentName.equals(Fields.DONE)) {
if (parser.nextToken() != XContentParser.Token.VALUE_NUMBER) {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]",
currentName);
}
doneShards = parser.intValue();
} else if (currentName.equals(Fields.FAILED)) {
if (parser.nextToken() != XContentParser.Token.VALUE_NUMBER) {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]",
currentName);
}
failedShards = parser.intValue();
} else if (currentName.equals(Fields.TOTAL)) {
if (parser.nextToken() != XContentParser.Token.VALUE_NUMBER) {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, expected number for field [{}]",
currentName);
}
totalShards = parser.intValue();
} else {
throw new ElasticsearchParseException("failed to parse snapshot shards stats, unexpected field [{}]", currentName);
}
} else {
throw new ElasticsearchParseException("failed to parse snapshot shards stats");
}
static final ConstructingObjectParser<SnapshotShardsStats, Void> PARSER = new ConstructingObjectParser<>(
Fields.SHARDS_STATS,
(Object[] parsedObjects) -> {
int i = 0;
int initializingShards = (int) parsedObjects[i++];
int startedShards = (int) parsedObjects[i++];
int finalizingShards = (int) parsedObjects[i++];
int doneShards = (int) parsedObjects[i++];
int failedShards = (int) parsedObjects[i++];
int totalShards = (int) parsedObjects[i];
return new SnapshotShardsStats(initializingShards, startedShards, finalizingShards, doneShards, failedShards, totalShards);
}
return new SnapshotShardsStats(initializingShards, startedShards, finalizingShards, doneShards, failedShards, totalShards);
);
static {
PARSER.declareInt(constructorArg(), new ParseField(Fields.INITIALIZING));
PARSER.declareInt(constructorArg(), new ParseField(Fields.STARTED));
PARSER.declareInt(constructorArg(), new ParseField(Fields.FINALIZING));
PARSER.declareInt(constructorArg(), new ParseField(Fields.DONE));
PARSER.declareInt(constructorArg(), new ParseField(Fields.FAILED));
PARSER.declareInt(constructorArg(), new ParseField(Fields.TOTAL));
}

public static SnapshotShardsStats fromXContent(XContentParser parser) throws IOException {
return PARSER.apply(parser, null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,13 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par
}

public static SnapshotStats fromXContent(XContentParser parser) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
XContentParser.Token token;
// Parse this old school style instead of using the ObjectParser since there's an impedance mismatch between how the
// object has historically been written as JSON versus how it is structured in Java.
XContentParser.Token token = parser.currentToken();
if (token == null) {
token = parser.nextToken();
}
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation);
long startTime = 0;
long time = 0;
int incrementalFileCount = 0;
Expand Down
Loading

0 comments on commit 104b723

Please sign in to comment.