Implement toXContent on ShardOpertionFailureException
ShardOperationFailureException implementations alread provide structured exception support but it's not yet exposed on the interface. This change allows nice rendering of structured REST exceptions also if searches fail on only a subset of the shards etc. Closes #11017
This commit is contained in:
parent
f7696ec149
commit
8b8ba9a44f
|
@ -22,16 +22,18 @@ package org.elasticsearch;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexException;
|
||||
import org.elasticsearch.rest.HasRestHeaders;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A base class for all elasticsearch exceptions.
|
||||
|
@ -288,6 +290,4 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
|
|||
public String toString() {
|
||||
return ExceptionsHelper.detailedMessage(this).trim();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -22,15 +22,21 @@ package org.elasticsearch;
|
|||
import org.apache.lucene.index.CorruptIndexException;
|
||||
import org.apache.lucene.index.IndexFormatTooNewException;
|
||||
import org.apache.lucene.index.IndexFormatTooOldException;
|
||||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexException;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -214,4 +220,59 @@ public final class ExceptionsHelper {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deduplicate the failures by exception message and index.
|
||||
*/
|
||||
public static ShardOperationFailedException[] groupBy(ShardOperationFailedException[] failures) {
|
||||
List<ShardOperationFailedException> uniqueFailures = new ArrayList<>();
|
||||
Set<GroupBy> reasons = new HashSet<>();
|
||||
for (ShardOperationFailedException failure : failures) {
|
||||
GroupBy reason = new GroupBy(failure.getCause());
|
||||
if (reasons.contains(reason) == false) {
|
||||
reasons.add(reason);
|
||||
uniqueFailures.add(failure);
|
||||
}
|
||||
}
|
||||
return uniqueFailures.toArray(new ShardOperationFailedException[0]);
|
||||
}
|
||||
|
||||
static class GroupBy {
|
||||
final String reason;
|
||||
final Index index;
|
||||
final Class<? extends Throwable> causeType;
|
||||
|
||||
public GroupBy(Throwable t) {
|
||||
if (t instanceof IndexException) {
|
||||
index = ((IndexException) t).index();
|
||||
} else {
|
||||
index = null;
|
||||
}
|
||||
reason = t.getMessage();
|
||||
causeType = t.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GroupBy groupBy = (GroupBy) o;
|
||||
|
||||
if (!causeType.equals(groupBy.causeType)) return false;
|
||||
if (index != null ? !index.equals(groupBy.index) : groupBy.index != null) return false;
|
||||
if (reason != null ? !reason.equals(groupBy.reason) : groupBy.reason != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = reason != null ? reason.hashCode() : 0;
|
||||
result = 31 * result + (index != null ? index.hashCode() : 0);
|
||||
result = 31 * result + causeType.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,6 +231,11 @@ public abstract class ActionWriteResponse extends ActionResponse {
|
|||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this failure occurred on a primary shard.
|
||||
* (this only reports true for delete by query)
|
||||
|
|
|
@ -20,16 +20,23 @@
|
|||
package org.elasticsearch.action;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexException;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An exception indicating that a failure occurred performing an operation on the shard.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface ShardOperationFailedException extends Streamable, Serializable {
|
||||
public interface ShardOperationFailedException extends Streamable, Serializable, ToXContent {
|
||||
|
||||
/**
|
||||
* The index the operation failed on. Might return <tt>null</tt> if it can't be derived.
|
||||
|
@ -50,4 +57,9 @@ public interface ShardOperationFailedException extends Streamable, Serializable
|
|||
* The status of the failure.
|
||||
*/
|
||||
RestStatus status();
|
||||
|
||||
/**
|
||||
* The cause of this failure
|
||||
*/
|
||||
Throwable getCause();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.action.bulk;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.action.ActionWriteResponse;
|
||||
import org.elasticsearch.action.delete.DeleteResponse;
|
||||
|
@ -27,6 +28,7 @@ import org.elasticsearch.action.update.UpdateResponse;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -44,26 +46,17 @@ public class BulkItemResponse implements Streamable {
|
|||
private final String index;
|
||||
private final String type;
|
||||
private final String id;
|
||||
private final String message;
|
||||
private final Throwable cause;
|
||||
private final RestStatus status;
|
||||
|
||||
public Failure(String index, String type, String id, Throwable t) {
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.message = t.toString();
|
||||
this.cause = t;
|
||||
this.status = ExceptionsHelper.status(t);
|
||||
}
|
||||
|
||||
|
||||
public Failure(String index, String type, String id, String message, RestStatus status) {
|
||||
this.index = index;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.message = message;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The index name of the action.
|
||||
*/
|
||||
|
@ -89,7 +82,7 @@ public class BulkItemResponse implements Streamable {
|
|||
* The failure message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
return this.cause.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,6 +91,10 @@ public class BulkItemResponse implements Streamable {
|
|||
public RestStatus getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
||||
private int id;
|
||||
|
@ -265,9 +262,8 @@ public class BulkItemResponse implements Streamable {
|
|||
String fIndex = in.readString();
|
||||
String fType = in.readString();
|
||||
String fId = in.readOptionalString();
|
||||
String fMessage = in.readString();
|
||||
RestStatus status = RestStatus.readFrom(in);
|
||||
failure = new Failure(fIndex, fType, fId, fMessage, status);
|
||||
Throwable throwable = in.readThrowable();
|
||||
failure = new Failure(fIndex, fType, fId, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,8 +291,7 @@ public class BulkItemResponse implements Streamable {
|
|||
out.writeString(failure.getIndex());
|
||||
out.writeString(failure.getType());
|
||||
out.writeOptionalString(failure.getId());
|
||||
out.writeString(failure.getMessage());
|
||||
RestStatus.writeTo(out, failure.getStatus());
|
||||
out.writeThrowable(failure.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ public class TransportBulkAction extends HandledTransportAction<BulkRequest, Bul
|
|||
MappingMetaData mappingMd = clusterState.metaData().index(concreteIndex).mappingOrDefault(updateRequest.type());
|
||||
if (mappingMd != null && mappingMd.routing().required() && updateRequest.routing() == null) {
|
||||
BulkItemResponse.Failure failure = new BulkItemResponse.Failure(updateRequest.index(), updateRequest.type(),
|
||||
updateRequest.id(), "routing is required for this item", RestStatus.BAD_REQUEST);
|
||||
updateRequest.id(), new IllegalArgumentException("routing is required for this item"));
|
||||
responses.set(i, new BulkItemResponse(i, updateRequest.type(), failure));
|
||||
continue;
|
||||
}
|
||||
|
@ -328,21 +328,19 @@ public class TransportBulkAction extends HandledTransportAction<BulkRequest, Bul
|
|||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
// create failures for all relevant requests
|
||||
String message = ExceptionsHelper.detailedMessage(e);
|
||||
RestStatus status = ExceptionsHelper.status(e);
|
||||
for (BulkItemRequest request : requests) {
|
||||
if (request.request() instanceof IndexRequest) {
|
||||
IndexRequest indexRequest = (IndexRequest) request.request();
|
||||
responses.set(request.id(), new BulkItemResponse(request.id(), indexRequest.opType().toString().toLowerCase(Locale.ENGLISH),
|
||||
new BulkItemResponse.Failure(concreteIndices.getConcreteIndex(indexRequest.index()), indexRequest.type(), indexRequest.id(), message, status)));
|
||||
new BulkItemResponse.Failure(concreteIndices.getConcreteIndex(indexRequest.index()), indexRequest.type(), indexRequest.id(), e)));
|
||||
} else if (request.request() instanceof DeleteRequest) {
|
||||
DeleteRequest deleteRequest = (DeleteRequest) request.request();
|
||||
responses.set(request.id(), new BulkItemResponse(request.id(), "delete",
|
||||
new BulkItemResponse.Failure(concreteIndices.getConcreteIndex(deleteRequest.index()), deleteRequest.type(), deleteRequest.id(), message, status)));
|
||||
new BulkItemResponse.Failure(concreteIndices.getConcreteIndex(deleteRequest.index()), deleteRequest.type(), deleteRequest.id(), e)));
|
||||
} else if (request.request() instanceof UpdateRequest) {
|
||||
UpdateRequest updateRequest = (UpdateRequest) request.request();
|
||||
responses.set(request.id(), new BulkItemResponse(request.id(), "update",
|
||||
new BulkItemResponse.Failure(concreteIndices.getConcreteIndex(updateRequest.index()), updateRequest.type(), updateRequest.id(), message, status)));
|
||||
new BulkItemResponse.Failure(concreteIndices.getConcreteIndex(updateRequest.index()), updateRequest.type(), updateRequest.id(), e)));
|
||||
}
|
||||
}
|
||||
if (counter.decrementAndGet() == 0) {
|
||||
|
|
|
@ -116,7 +116,7 @@ public class PercolateResponse extends BroadcastOperationResponse implements Ite
|
|||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.field(Fields.TOOK, tookInMillis);
|
||||
RestActions.buildBroadcastShardsHeader(builder, this);
|
||||
RestActions.buildBroadcastShardsHeader(builder, params, this);
|
||||
|
||||
builder.field(Fields.TOTAL, count);
|
||||
if (matches != null) {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.elasticsearch.action.search;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexException;
|
||||
|
@ -92,8 +94,8 @@ public class SearchPhaseExecutionException extends ElasticsearchException {
|
|||
builder.field("grouped", group); // notify that it's grouped
|
||||
builder.field("failed_shards");
|
||||
builder.startArray();
|
||||
ShardSearchFailure[] failures = params.paramAsBoolean("group_shard_failures", true) ? groupBy(shardFailures) : shardFailures;
|
||||
for (ShardSearchFailure failure : failures) {
|
||||
ShardOperationFailedException[] failures = params.paramAsBoolean("group_shard_failures", true) ? ExceptionsHelper.groupBy(shardFailures) : shardFailures;
|
||||
for (ShardOperationFailedException failure : failures) {
|
||||
builder.startObject();
|
||||
failure.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
|
@ -103,25 +105,11 @@ public class SearchPhaseExecutionException extends ElasticsearchException {
|
|||
|
||||
}
|
||||
|
||||
private ShardSearchFailure[] groupBy(ShardSearchFailure[] failures) {
|
||||
List<ShardSearchFailure> uniqueFailures = new ArrayList<>();
|
||||
Set<GroupBy> reasons = new HashSet<>();
|
||||
for (ShardSearchFailure failure : failures) {
|
||||
GroupBy reason = new GroupBy(failure.getCause());
|
||||
if (reasons.contains(reason) == false) {
|
||||
reasons.add(reason);
|
||||
uniqueFailures.add(failure);
|
||||
}
|
||||
}
|
||||
return uniqueFailures.toArray(new ShardSearchFailure[0]);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElasticsearchException[] guessRootCauses() {
|
||||
ShardSearchFailure[] failures = groupBy(shardFailures);
|
||||
ShardOperationFailedException[] failures = ExceptionsHelper.groupBy(shardFailures);
|
||||
List<ElasticsearchException> rootCauses = new ArrayList<>(failures.length);
|
||||
for (ShardSearchFailure failure : failures) {
|
||||
for (ShardOperationFailedException failure : failures) {
|
||||
ElasticsearchException[] guessRootCauses = ElasticsearchException.guessRootCauses(failure.getCause());
|
||||
rootCauses.addAll(Arrays.asList(guessRootCauses));
|
||||
}
|
||||
|
@ -132,42 +120,4 @@ public class SearchPhaseExecutionException extends ElasticsearchException {
|
|||
public String toString() {
|
||||
return buildMessage(phaseName, getMessage(), shardFailures);
|
||||
}
|
||||
|
||||
static class GroupBy {
|
||||
final String reason;
|
||||
final Index index;
|
||||
final Class<? extends Throwable> causeType;
|
||||
|
||||
public GroupBy(Throwable t) {
|
||||
if (t instanceof IndexException) {
|
||||
index = ((IndexException) t).index();
|
||||
} else {
|
||||
index = null;
|
||||
}
|
||||
reason = t.getMessage();
|
||||
causeType = t.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GroupBy groupBy = (GroupBy) o;
|
||||
|
||||
if (!causeType.equals(groupBy.causeType)) return false;
|
||||
if (index != null ? !index.equals(groupBy.index) : groupBy.index != null) return false;
|
||||
if (reason != null ? !reason.equals(groupBy.reason) : groupBy.reason != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = reason != null ? reason.hashCode() : 0;
|
||||
result = 31 * result + (index != null ? index.hashCode() : 0);
|
||||
result = 31 * result + causeType.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,7 @@ public class SearchResponse extends ActionResponse implements StatusToXContent {
|
|||
if (isTerminatedEarly() != null) {
|
||||
builder.field(Fields.TERMINATED_EARLY, isTerminatedEarly());
|
||||
}
|
||||
RestActions.buildBroadcastShardsHeader(builder, getTotalShards(), getSuccessfulShards(), getFailedShards(), getShardFailures());
|
||||
RestActions.buildBroadcastShardsHeader(builder, params, getTotalShards(), getSuccessfulShards(), getFailedShards(), getShardFailures());
|
||||
internalResponse.toXContent(builder, params);
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import static org.elasticsearch.search.SearchShardTarget.readSearchShardTarget;
|
|||
/**
|
||||
* Represents a failure to search on a specific shard.
|
||||
*/
|
||||
public class ShardSearchFailure implements ShardOperationFailedException, ToXContent {
|
||||
public class ShardSearchFailure implements ShardOperationFailedException {
|
||||
|
||||
public static final ShardSearchFailure[] EMPTY_ARRAY = new ShardSearchFailure[0];
|
||||
|
||||
|
@ -172,6 +172,7 @@ public class ShardSearchFailure implements ShardOperationFailedException, ToXCon
|
|||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import org.elasticsearch.ExceptionsHelper;
|
|||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.shard.IndexShardException;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
|
@ -81,6 +83,11 @@ public class DefaultShardOperationFailedException implements ShardOperationFaile
|
|||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public static DefaultShardOperationFailedException readShardOperationFailed(StreamInput in) throws IOException {
|
||||
DefaultShardOperationFailedException exp = new DefaultShardOperationFailedException();
|
||||
exp.readFrom(in);
|
||||
|
@ -114,4 +121,19 @@ public class DefaultShardOperationFailedException implements ShardOperationFaile
|
|||
public String toString() {
|
||||
return "[" + index + "][" + shardId + "] failed, reason [" + reason() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.field("shard", shardId());
|
||||
builder.field("index", index());
|
||||
builder.field("status", status.name());
|
||||
if (reason != null) {
|
||||
builder.field("reason");
|
||||
builder.startObject();
|
||||
ElasticsearchException.toXContent(builder, params, reason);
|
||||
builder.endObject();
|
||||
}
|
||||
return builder;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class RestClearIndicesCacheAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(ClearIndicesCacheResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class RestFlushAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(FlushResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public class RestOptimizeAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(OptimizeResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class RestRefreshAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(RefreshResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class RestIndicesSegmentsAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(IndicesSegmentResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
response.toXContent(builder, request);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
|
|
|
@ -103,7 +103,7 @@ public class RestIndicesStatsAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(IndicesStatsResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
response.toXContent(builder, request);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
|
|
|
@ -87,7 +87,7 @@ public class RestUpgradeAction extends BaseRestHandler {
|
|||
});
|
||||
}
|
||||
|
||||
void handlePost(RestRequest request, RestChannel channel, Client client) {
|
||||
void handlePost(final RestRequest request, RestChannel channel, Client client) {
|
||||
OptimizeRequest optimizeReq = new OptimizeRequest(Strings.splitStringByCommaToArray(request.param("index")));
|
||||
optimizeReq.flush(true);
|
||||
optimizeReq.upgrade(true);
|
||||
|
@ -97,7 +97,7 @@ public class RestUpgradeAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(OptimizeResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(OK, builder);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class RestValidateQueryAction extends BaseRestHandler {
|
|||
builder.startObject();
|
||||
builder.field("valid", response.isValid());
|
||||
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
|
||||
if (response.getQueryExplanation() != null && !response.getQueryExplanation().isEmpty()) {
|
||||
builder.startArray("explanations");
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.rest.action.bulk;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.action.ActionWriteResponse;
|
||||
import org.elasticsearch.action.WriteConsistencyLevel;
|
||||
import org.elasticsearch.action.bulk.BulkItemResponse;
|
||||
|
@ -102,7 +103,9 @@ public class RestBulkAction extends BaseRestHandler {
|
|||
}
|
||||
if (itemResponse.isFailed()) {
|
||||
builder.field(Fields.STATUS, itemResponse.getFailure().getStatus().getStatus());
|
||||
builder.field(Fields.ERROR, itemResponse.getFailure().getMessage());
|
||||
builder.startObject(Fields.ERROR);
|
||||
ElasticsearchException.toXContent(builder, request, itemResponse.getFailure().getCause());
|
||||
builder.endObject();
|
||||
} else {
|
||||
ActionWriteResponse.ShardInfo shardInfo = itemResponse.getResponse().getShardInfo();
|
||||
shardInfo.toXContent(builder, request);
|
||||
|
|
|
@ -85,7 +85,7 @@ public class RestCountAction extends BaseRestHandler {
|
|||
builder.field("terminated_early", response.terminatedEarly());
|
||||
}
|
||||
builder.field("count", response.getCount());
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
|
||||
builder.endObject();
|
||||
return new BytesRestResponse(response.status(), builder);
|
||||
|
|
|
@ -62,7 +62,7 @@ public class RestFieldStatsAction extends BaseRestHandler {
|
|||
@Override
|
||||
public RestResponse buildResponse(FieldStatsResponse response, XContentBuilder builder) throws Exception {
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
|
||||
builder.startObject("indices");
|
||||
for (Map.Entry<String, Map<String, FieldStats>> entry1 : response.getIndicesMergedFieldStats().entrySet()) {
|
||||
|
|
|
@ -72,7 +72,7 @@ public class RestSuggestAction extends BaseRestHandler {
|
|||
public RestResponse buildResponse(SuggestResponse response, XContentBuilder builder) throws Exception {
|
||||
RestStatus restStatus = RestStatus.status(response.getSuccessfulShards(), response.getTotalShards(), response.getShardFailures());
|
||||
builder.startObject();
|
||||
buildBroadcastShardsHeader(builder, response);
|
||||
buildBroadcastShardsHeader(builder, request, response);
|
||||
Suggest suggest = response.getSuggest();
|
||||
if (suggest != null) {
|
||||
suggest.toXContent(builder, request);
|
||||
|
|
|
@ -19,16 +19,14 @@
|
|||
|
||||
package org.elasticsearch.rest.action.support;
|
||||
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.action.support.QuerySourceBuilder;
|
||||
import org.elasticsearch.action.support.broadcast.BroadcastOperationResponse;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.lucene.uid.Versions;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.*;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.QueryStringQueryBuilder;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
@ -62,33 +60,23 @@ public class RestActions {
|
|||
static final XContentBuilderString SUCCESSFUL = new XContentBuilderString("successful");
|
||||
static final XContentBuilderString FAILED = new XContentBuilderString("failed");
|
||||
static final XContentBuilderString FAILURES = new XContentBuilderString("failures");
|
||||
static final XContentBuilderString INDEX = new XContentBuilderString("index");
|
||||
static final XContentBuilderString SHARD = new XContentBuilderString("shard");
|
||||
static final XContentBuilderString STATUS = new XContentBuilderString("status");
|
||||
static final XContentBuilderString REASON = new XContentBuilderString("reason");
|
||||
}
|
||||
|
||||
public static void buildBroadcastShardsHeader(XContentBuilder builder, BroadcastOperationResponse response) throws IOException {
|
||||
buildBroadcastShardsHeader(builder, response.getTotalShards(), response.getSuccessfulShards(), response.getFailedShards(), response.getShardFailures());
|
||||
public static void buildBroadcastShardsHeader(XContentBuilder builder, ToXContent.Params params, BroadcastOperationResponse response) throws IOException {
|
||||
buildBroadcastShardsHeader(builder, params, response.getTotalShards(), response.getSuccessfulShards(), response.getFailedShards(), response.getShardFailures());
|
||||
}
|
||||
|
||||
public static void buildBroadcastShardsHeader(XContentBuilder builder, int total, int successful, int failed, ShardOperationFailedException[] shardFailures) throws IOException {
|
||||
public static void buildBroadcastShardsHeader(XContentBuilder builder, ToXContent.Params params, int total, int successful, int failed, ShardOperationFailedException[] shardFailures) throws IOException {
|
||||
builder.startObject(Fields._SHARDS);
|
||||
builder.field(Fields.TOTAL, total);
|
||||
builder.field(Fields.SUCCESSFUL, successful);
|
||||
builder.field(Fields.FAILED, failed);
|
||||
if (shardFailures != null && shardFailures.length > 0) {
|
||||
builder.startArray(Fields.FAILURES);
|
||||
for (ShardOperationFailedException shardFailure : shardFailures) {
|
||||
final boolean group = params.paramAsBoolean("group_shard_failures", true); // we group by default
|
||||
for (ShardOperationFailedException shardFailure : group ? ExceptionsHelper.groupBy(shardFailures) : shardFailures) {
|
||||
builder.startObject();
|
||||
if (shardFailure.index() != null) {
|
||||
builder.field(Fields.INDEX, shardFailure.index(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
}
|
||||
if (shardFailure.shardId() != -1) {
|
||||
builder.field(Fields.SHARD, shardFailure.shardId());
|
||||
}
|
||||
builder.field(Fields.STATUS, shardFailure.status().getStatus());
|
||||
builder.field(Fields.REASON, shardFailure.reason());
|
||||
shardFailure.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
|
|
|
@ -255,7 +255,9 @@ public class Snapshot implements Comparable<Snapshot>, ToXContent {
|
|||
builder.field(Fields.SUCCESSFUL_SHARDS, successfulShards);
|
||||
builder.startArray(Fields.FAILURES);
|
||||
for (SnapshotShardFailure shardFailure : shardFailures) {
|
||||
SnapshotShardFailure.toXContent(shardFailure, builder, params);
|
||||
builder.startObject();
|
||||
shardFailure.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
|
|
|
@ -223,7 +223,9 @@ public class SnapshotInfo implements ToXContent, Streamable {
|
|||
}
|
||||
builder.startArray(Fields.FAILURES);
|
||||
for (SnapshotShardFailure shardFailure : shardFailures) {
|
||||
SnapshotShardFailure.toXContent(shardFailure, builder, params);
|
||||
builder.startObject();
|
||||
shardFailure.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.startObject(Fields.SHARDS);
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
|||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -106,6 +108,11 @@ public class SnapshotShardFailure implements ShardOperationFailedException {
|
|||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return new IndexShardSnapshotFailedException(new ShardId(index, shardId), reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node id where failure occurred
|
||||
*
|
||||
|
@ -162,13 +169,7 @@ public class SnapshotShardFailure implements ShardOperationFailedException {
|
|||
*/
|
||||
public static void toXContent(SnapshotShardFailure snapshotShardFailure, XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.startObject();
|
||||
if (snapshotShardFailure.nodeId != null) {
|
||||
builder.field("node_id", snapshotShardFailure.nodeId);
|
||||
}
|
||||
builder.field("index", snapshotShardFailure.index);
|
||||
builder.field("reason", snapshotShardFailure.reason);
|
||||
builder.field("shard_id", snapshotShardFailure.shardId);
|
||||
builder.field("status", snapshotShardFailure.status.name());
|
||||
snapshotShardFailure.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
|
@ -212,4 +213,16 @@ public class SnapshotShardFailure implements ShardOperationFailedException {
|
|||
}
|
||||
return snapshotShardFailure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.field("index", index);
|
||||
builder.field("shard_id", shardId);
|
||||
builder.field("reason", reason);
|
||||
if (nodeId != null) {
|
||||
builder.field("node_id", nodeId);
|
||||
}
|
||||
builder.field("status", status.name());
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue