Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
420fa8c
Add ParsedAggregation as base Aggregation impl for high level client
javanna Apr 7, 2017
67e0870
add class to suppressions list for line length check
javanna Apr 7, 2017
39e7912
Merge branch 'master' into feature/client_aggs_parsing
javanna Apr 7, 2017
306ef08
Align ParsedAggregation meta to InternalAggregation behaviour
javanna Apr 7, 2017
8464b47
[TEST] replace FareRestRequest usage with ToXContent.MapParams
javanna Apr 7, 2017
9e7b020
Remove TODO on un-deprecating NamedContentRegistry.Entry ctor that ta…
javanna Apr 7, 2017
12e8a45
remove some more TODOs from ParsedAggregation
javanna Apr 7, 2017
f538d7b
Merge branch 'master' into feature/client_aggs_parsing
javanna Apr 10, 2017
3565328
Adding ParsedCardinality (#23973)
cbuescher Apr 12, 2017
cf89fb8
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 12, 2017
7f730c9
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx Apr 13, 2017
5ccb4a0
fix typo in ParsedCardinality comment and add //norelease comment on …
javanna Apr 14, 2017
c0036d8
Add parsing for percentiles ranks (#23974)
tlrx Apr 18, 2017
67a9696
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx Apr 18, 2017
c1ba699
AbstractParsedPercentiles should use Percentile class (#24160)
tlrx Apr 18, 2017
75fdc94
Adding parsing for InternalMax and InternalMin
cbuescher Apr 18, 2017
695b285
Adding parsing for InternalSum
cbuescher Apr 18, 2017
5f96972
Adding parsing for InternalAvg
cbuescher Apr 18, 2017
bc646cf
Adding parsing for InternalValueCount
cbuescher Apr 18, 2017
210e101
Minor changes in ParsedCardinality
cbuescher Apr 18, 2017
5717ac3
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx Apr 19, 2017
bf5cfab
Fix checkstyle violation
tlrx Apr 19, 2017
4562c8a
Add parsing for InternalSimpleValue and InternalDerivative (#24162)
cbuescher Apr 19, 2017
e12339a
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 19, 2017
11da773
Add parsing methods for Percentiles aggregations (#24183)
tlrx Apr 20, 2017
2b14db9
Remove @Repeat(iterations = 1000) in tests
tlrx Apr 20, 2017
6e22a1e
Add parsing for InternalBucketMetricValue (#24182)
cbuescher Apr 20, 2017
d0df1ed
[Test] Always check the XContent equivalent when parsing aggregation…
tlrx Apr 20, 2017
35946a1
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx Apr 20, 2017
c8fc30a
[Test] Expose AbstractPercentilesTestCase.randomPercents()
tlrx Apr 20, 2017
d9916f2
Merge branch 'master' into feature/client_aggs_parsing
javanna Apr 20, 2017
4a69b65
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 21, 2017
adef5e2
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx Apr 21, 2017
5541deb
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 24, 2017
1cb34b5
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 24, 2017
768420d
Add parsing for InternalStats (#24239)
cbuescher Apr 25, 2017
0e31a21
Add parsing for InternalExtendedStats (#24284)
cbuescher Apr 25, 2017
fede0ba
Correcting 140 character line length
cbuescher Apr 26, 2017
774368d
Add parsing for InternalStatsBucket and InternalExtendedStatsBucket (…
cbuescher Apr 26, 2017
e2b95f9
Fix order of static field declarations for parser
cbuescher Apr 26, 2017
1f22115
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 26, 2017
b46c39e
Fixed another sneaky LineLength violation
cbuescher Apr 26, 2017
93415cd
Add parsing for InternalPercentilesBucket (#24330)
cbuescher Apr 27, 2017
9cb3666
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 27, 2017
a6c38b8
Add parsing for InternalGeoBounds (#24365)
cbuescher Apr 28, 2017
0d5cca8
Fixing checktyle error for modifier order
cbuescher Apr 28, 2017
db07a34
Merge branch 'master' into feature/client_aggs_parsing
cbuescher Apr 28, 2017
4d14143
Add parsing for InternalGeoCentroid (#24371)
cbuescher Apr 28, 2017
60866da
Merge branch 'master' into feature/client_aggs_parsing
javanna May 2, 2017
fbd793d
Introduce SearchResponseSections base class (#24442)
javanna May 3, 2017
2ac90b3
Add parsing methods for InternalDateHistogram and InternalHistogram (…
tlrx May 3, 2017
62c3733
Merge branch 'master' into feature/client_aggs_parsing
javanna May 3, 2017
c7c524d
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx May 5, 2017
1959fd6
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 9, 2017
c5bdbec
[TEST] Add test for Aggregations#fromXContent (#24524)
javanna May 9, 2017
37dc165
[TEST] add test to verify that no aggs have been forgotten in Aggrega…
javanna May 9, 2017
01b9760
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 10, 2017
3c66ac0
Add parsing for String/Long/Double Terms aggregations (#24521)
tlrx May 10, 2017
2178491
Fix checkstyle violation
tlrx May 10, 2017
7c97296
[Test] Reference Terms aggregations in AggregationsTests
tlrx May 10, 2017
bf718a6
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx May 10, 2017
3201e22
Fix merging conflicts
tlrx May 10, 2017
2e602d6
[TEST] reset subAggregationsSupplier in AggregationsTests to empty su…
javanna May 10, 2017
570390a
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 11, 2017
c4fc8ed
Add parsing for single bucket aggregations (#24564)
cbuescher May 11, 2017
744b1af
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 12, 2017
ee1303a
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 12, 2017
29a5694
Add parsing method to GeoHashGrid aggregation (#24589)
tlrx May 12, 2017
b9d2ecc
Add parsing methods to Range aggregations (#24583)
tlrx May 12, 2017
322a4c1
Fix msearch rest test using typed_keys
cbuescher May 12, 2017
bb59ee5
Revert changing the InternalSampler type constant (#24667)
cbuescher May 15, 2017
42e8d4b
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 15, 2017
0b688a8
Small improvement in InternalAggregationTestCase test setup after cha…
cbuescher May 15, 2017
60505c9
Add parsing for InternalFilters aggregation (#24648)
cbuescher May 15, 2017
5fb04fa
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx May 15, 2017
059b23e
Merge branch 'master' into feature/client_aggs_parsing
cbuescher May 16, 2017
ef7c2e6
Add parsing for InternalAdjacencyMatrix aggregation (#24700)
cbuescher May 16, 2017
d5fc520
Add parsing to Significant Terms aggregations (#24682)
tlrx May 16, 2017
ce7326e
Merge branch 'master' into feature/client_aggs_parsing
javanna May 17, 2017
9fc9db2
Add parsing for InternalScriptedMetric aggregation (#24738)
cbuescher May 17, 2017
da669f0
Add fromXContent method to SearchResponse (#24720)
javanna May 17, 2017
25fceb8
Add parsing method for binary range aggregation (#24706)
tlrx May 18, 2017
0558753
Add parsing method for Top Hits aggregation (#24717)
tlrx May 18, 2017
f10391e
Fix checkstyle violation in ParsedScriptedMetric
tlrx May 18, 2017
eeef2e6
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx May 18, 2017
dd731d9
Add parsing method for Matrix Stats (#24746)
tlrx May 19, 2017
4c34ea8
Remove //norelease and cleans up somet aggregations tests (#24789)
tlrx May 19, 2017
83aa00b
Merge remote-tracking branch 'origin/master' into feature/client_aggs…
tlrx May 19, 2017
91d7bf4
Remove compareTerm() method in parsed Significant Terms aggregations
tlrx May 19, 2017
05acc43
Fix InternalExtendedStatsTests setUp
cbuescher May 19, 2017
ad3658a
[Test] Remove ParsedAggregationTests (#24791)
tlrx May 19, 2017
0b8da31
SearchResponse#fromXContent to not require START_OBJECT as current to…
javanna May 19, 2017
db04903
Merge branch 'master' into feature/client_aggs_parsing
javanna May 19, 2017
726e6c4
Move getType to Aggregation interface (#24822)
javanna May 22, 2017
7a3e38e
Merge branch 'master' into feature/client_aggs_parsing
javanna May 22, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions buildSrc/src/main/resources/checkstyle_suppressions.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">

<suppressions>
<!-- On Windows, Checkstyle matches files using \ path separator -->
Expand Down Expand Up @@ -795,4 +795,4 @@
<suppress files="test[/\\]framework[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]test[/\\]hamcrest[/\\]ElasticsearchAssertions.java" checks="LineLength" />
<suppress files="test[/\\]framework[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]test[/\\]store[/\\]MockFSDirectoryService.java" checks="LineLength" />
<suppress files="test[/\\]framework[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]test[/\\]store[/\\]MockFSIndexStore.java" checks="LineLength" />
</suppressions>
</suppressions>
114 changes: 104 additions & 10 deletions core/src/main/java/org/elasticsearch/action/search/SearchResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,46 @@

import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.StatusToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.RestActions;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.internal.InternalSearchResponse;
import org.elasticsearch.search.profile.ProfileShardResult;
import org.elasticsearch.search.profile.SearchProfileShardResults;
import org.elasticsearch.search.suggest.Suggest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.elasticsearch.action.search.ShardSearchFailure.readShardSearchFailure;
import static org.elasticsearch.search.internal.InternalSearchResponse.readInternalSearchResponse;
import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownField;
import static org.elasticsearch.common.xcontent.XContentParserUtils.throwUnknownToken;


/**
* A response of a search request.
*/
public class SearchResponse extends ActionResponse implements StatusToXContentObject {

private InternalSearchResponse internalResponse;
private static final ParseField SCROLL_ID = new ParseField("_scroll_id");
private static final ParseField TOOK = new ParseField("took");
private static final ParseField TIMED_OUT = new ParseField("timed_out");
private static final ParseField TERMINATED_EARLY = new ParseField("terminated_early");
private static final ParseField NUM_REDUCE_PHASES = new ParseField("num_reduce_phases");

private SearchResponseSections internalResponse;

private String scrollId;

Expand All @@ -61,7 +75,7 @@ public class SearchResponse extends ActionResponse implements StatusToXContentOb
public SearchResponse() {
}

public SearchResponse(InternalSearchResponse internalResponse, String scrollId, int totalShards, int successfulShards,
public SearchResponse(SearchResponseSections internalResponse, String scrollId, int totalShards, int successfulShards,
long tookInMillis, ShardSearchFailure[] shardFailures) {
this.internalResponse = internalResponse;
this.scrollId = scrollId;
Expand Down Expand Up @@ -176,7 +190,8 @@ public void scrollId(String scrollId) {
*
* @return The profile results or an empty map
*/
@Nullable public Map<String, ProfileShardResult> getProfileResults() {
@Nullable
public Map<String, ProfileShardResult> getProfileResults() {
return internalResponse.profile();
}

Expand All @@ -190,26 +205,105 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws

public XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException {
if (scrollId != null) {
builder.field("_scroll_id", scrollId);
builder.field(SCROLL_ID.getPreferredName(), scrollId);
}
builder.field("took", tookInMillis);
builder.field("timed_out", isTimedOut());
builder.field(TOOK.getPreferredName(), tookInMillis);
builder.field(TIMED_OUT.getPreferredName(), isTimedOut());
if (isTerminatedEarly() != null) {
builder.field("terminated_early", isTerminatedEarly());
builder.field(TERMINATED_EARLY.getPreferredName(), isTerminatedEarly());
}
if (getNumReducePhases() != 1) {
builder.field("num_reduce_phases", getNumReducePhases());
builder.field(NUM_REDUCE_PHASES.getPreferredName(), getNumReducePhases());
}
RestActions.buildBroadcastShardsHeader(builder, params, getTotalShards(), getSuccessfulShards(), getFailedShards(),
getShardFailures());
internalResponse.toXContent(builder, params);
return builder;
}

public static SearchResponse fromXContent(XContentParser parser) throws IOException {
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
XContentParser.Token token;
String currentFieldName = null;
SearchHits hits = null;
Aggregations aggs = null;
Suggest suggest = null;
SearchProfileShardResults profile = null;
boolean timedOut = false;
Boolean terminatedEarly = null;
int numReducePhases = 1;
long tookInMillis = -1;
int successfulShards = -1;
int totalShards = -1;
String scrollId = null;
List<ShardSearchFailure> failures = new ArrayList<>();
while((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (SCROLL_ID.match(currentFieldName)) {
scrollId = parser.text();
} else if (TOOK.match(currentFieldName)) {
tookInMillis = parser.longValue();
} else if (TIMED_OUT.match(currentFieldName)) {
timedOut = parser.booleanValue();
} else if (TERMINATED_EARLY.match(currentFieldName)) {
terminatedEarly = parser.booleanValue();
} else if (NUM_REDUCE_PHASES.match(currentFieldName)) {
numReducePhases = parser.intValue();
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
}
} else if (token == XContentParser.Token.START_OBJECT) {
if (SearchHits.Fields.HITS.equals(currentFieldName)) {
hits = SearchHits.fromXContent(parser);
} else if (Aggregations.AGGREGATIONS_FIELD.equals(currentFieldName)) {
aggs = Aggregations.fromXContent(parser);
} else if (Suggest.NAME.equals(currentFieldName)) {
suggest = Suggest.fromXContent(parser);
} else if (SearchProfileShardResults.PROFILE_FIELD.equals(currentFieldName)) {
profile = SearchProfileShardResults.fromXContent(parser);
} else if (RestActions._SHARDS_FIELD.match(currentFieldName)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token.isValue()) {
if (RestActions.FAILED_FIELD.match(currentFieldName)) {
parser.intValue(); // we don't need it but need to consume it
} else if (RestActions.SUCCESSFUL_FIELD.match(currentFieldName)) {
successfulShards = parser.intValue();
} else if (RestActions.TOTAL_FIELD.match(currentFieldName)) {
totalShards = parser.intValue();
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
}
} else if (token == XContentParser.Token.START_ARRAY) {
if (RestActions.FAILURES_FIELD.match(currentFieldName)) {
while((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
failures.add(ShardSearchFailure.fromXContent(parser));
}
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
}
} else {
throwUnknownToken(token, parser.getTokenLocation());
}
}
} else {
throwUnknownField(currentFieldName, parser.getTokenLocation());
}
}
}
SearchResponseSections searchResponseSections = new SearchResponseSections(hits, aggs, suggest, timedOut, terminatedEarly,
profile, numReducePhases);
return new SearchResponse(searchResponseSections, scrollId, totalShards, successfulShards, tookInMillis,
failures.toArray(new ShardSearchFailure[failures.size()]));
}

@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
internalResponse = readInternalSearchResponse(in);
internalResponse = new InternalSearchResponse(in);
totalShards = in.readVInt();
successfulShards = in.readVInt();
int size = in.readVInt();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.action.search;

import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.profile.ProfileShardResult;
import org.elasticsearch.search.profile.SearchProfileShardResults;
import org.elasticsearch.search.suggest.Suggest;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

/**
* Base class that holds the various sections which a search response is
* composed of (hits, aggs, suggestions etc.) and allows to retrieve them.
*
* The reason why this class exists is that the high level REST client uses its own classes
* to parse aggregations into, which are not serializable. This is the common part that can be
* shared between core and client.
*/
public class SearchResponseSections implements ToXContent {

protected final SearchHits hits;
protected final Aggregations aggregations;
protected final Suggest suggest;
protected final SearchProfileShardResults profileResults;
protected final boolean timedOut;
protected final Boolean terminatedEarly;
protected final int numReducePhases;

public SearchResponseSections(SearchHits hits, Aggregations aggregations, Suggest suggest, boolean timedOut, Boolean terminatedEarly,
SearchProfileShardResults profileResults, int numReducePhases) {
this.hits = hits;
this.aggregations = aggregations;
this.suggest = suggest;
this.profileResults = profileResults;
this.timedOut = timedOut;
this.terminatedEarly = terminatedEarly;
this.numReducePhases = numReducePhases;
}

public final boolean timedOut() {
return this.timedOut;
}

public final Boolean terminatedEarly() {
return this.terminatedEarly;
}

public final SearchHits hits() {
return hits;
}

public final Aggregations aggregations() {
return aggregations;
}

public final Suggest suggest() {
return suggest;
}

/**
* Returns the number of reduce phases applied to obtain this search response
*/
public final int getNumReducePhases() {
return numReducePhases;
}

/**
* Returns the profile results for this search response (including all shards).
* An empty map is returned if profiling was not enabled
*
* @return Profile results
*/
public final Map<String, ProfileShardResult> profile() {
if (profileResults == null) {
return Collections.emptyMap();
}
return profileResults.getShardResults();
}

@Override
public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
hits.toXContent(builder, params);
if (aggregations != null) {
aggregations.toXContent(builder, params);
}
if (suggest != null) {
suggest.toXContent(builder, params);
}
if (profileResults != null) {
profileResults.toXContent(builder, params);
}
return builder;
}

protected void writeTo(StreamOutput out) throws IOException {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ public enum ValueType {
FLOAT(VALUE_NUMBER, VALUE_STRING),
FLOAT_OR_NULL(VALUE_NUMBER, VALUE_STRING, VALUE_NULL),
DOUBLE(VALUE_NUMBER, VALUE_STRING),
DOUBLE_OR_NULL(VALUE_NUMBER, VALUE_STRING, VALUE_NULL),
LONG(VALUE_NUMBER, VALUE_STRING),
LONG_OR_NULL(VALUE_NUMBER, VALUE_STRING, VALUE_NULL),
INT(VALUE_NUMBER, VALUE_STRING),
Expand All @@ -411,7 +412,8 @@ public enum ValueType {
OBJECT_OR_STRING(START_OBJECT, VALUE_STRING),
OBJECT_ARRAY_BOOLEAN_OR_STRING(START_OBJECT, START_ARRAY, VALUE_BOOLEAN, VALUE_STRING),
OBJECT_ARRAY_OR_STRING(START_OBJECT, START_ARRAY, VALUE_STRING),
VALUE(VALUE_BOOLEAN, VALUE_NULL, VALUE_EMBEDDED_OBJECT, VALUE_NUMBER, VALUE_STRING);
VALUE(VALUE_BOOLEAN, VALUE_NULL, VALUE_EMBEDDED_OBJECT, VALUE_NUMBER, VALUE_STRING),
VALUE_OBJECT_ARRAY(VALUE_BOOLEAN, VALUE_NULL, VALUE_EMBEDDED_OBJECT, VALUE_NUMBER, VALUE_STRING, START_OBJECT, START_ARRAY);

private final EnumSet<XContentParser.Token> tokens;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,9 @@ public static Object parseStoredFieldsValue(XContentParser parser) throws IOExce
}

/**
* This method expects that the current token is a {@code XContentParser.Token.FIELD_NAME} and
* that the current field name is the concatenation of a type, delimiter and name (ex: terms#foo
* where "terms" refers to the type of a registered {@link NamedXContentRegistry.Entry}, "#" is
* the delimiter and "foo" the name of the object to parse).
* This method expects that the current field name is the concatenation of a type, a delimiter and a name
* (ex: terms#foo where "terms" refers to the type of a registered {@link NamedXContentRegistry.Entry},
* "#" is the delimiter and "foo" the name of the object to parse).
*
* The method splits the field's name to extract the type and name and then parses the object
* using the {@link XContentParser#namedObject(Class, String, Object)} method.
Expand All @@ -128,7 +127,6 @@ public static Object parseStoredFieldsValue(XContentParser parser) throws IOExce
* from the field's name
*/
public static <T> T parseTypedKeysObject(XContentParser parser, String delimiter, Class<T> objectClass) throws IOException {
ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
String currentFieldName = parser.currentName();
if (Strings.hasLength(currentFieldName)) {
int position = currentFieldName.indexOf(delimiter);
Expand Down
17 changes: 12 additions & 5 deletions core/src/main/java/org/elasticsearch/rest/action/RestActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.elasticsearch.action.support.broadcast.BroadcastResponse;
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.lucene.uid.Versions;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContent.Params;
Expand All @@ -46,6 +47,12 @@

public class RestActions {

public static final ParseField _SHARDS_FIELD = new ParseField("_shards");
public static final ParseField TOTAL_FIELD = new ParseField("total");
public static final ParseField SUCCESSFUL_FIELD = new ParseField("successful");
public static final ParseField FAILED_FIELD = new ParseField("failed");
public static final ParseField FAILURES_FIELD = new ParseField("failures");

public static long parseVersion(RestRequest request) {
if (request.hasParam("version")) {
return request.paramAsLong("version", Versions.MATCH_ANY);
Expand All @@ -71,12 +78,12 @@ public static void buildBroadcastShardsHeader(XContentBuilder builder, Params pa
public static void buildBroadcastShardsHeader(XContentBuilder builder, Params params,
int total, int successful, int failed,
ShardOperationFailedException[] shardFailures) throws IOException {
builder.startObject("_shards");
builder.field("total", total);
builder.field("successful", successful);
builder.field("failed", failed);
builder.startObject(_SHARDS_FIELD.getPreferredName());
builder.field(TOTAL_FIELD.getPreferredName(), total);
builder.field(SUCCESSFUL_FIELD.getPreferredName(), successful);
builder.field(FAILED_FIELD.getPreferredName(), failed);
if (shardFailures != null && shardFailures.length > 0) {
builder.startArray("failures");
builder.startArray(FAILURES_FIELD.getPreferredName());
final boolean group = params.paramAsBoolean("group_shard_failures", true); // we group by default
for (ShardOperationFailedException shardFailure : group ? ExceptionsHelper.groupBy(shardFailures) : shardFailures) {
builder.startObject();
Expand Down
Loading