Search: When a search request failed completely (all shards fail) return a proper HTTP status code, closes #1035.
This commit is contained in:
parent
bbd73d5afa
commit
db6f5a7146
|
@ -27,6 +27,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.search.SearchHits;
|
||||
import org.elasticsearch.search.facet.Facets;
|
||||
import org.elasticsearch.search.internal.InternalSearchResponse;
|
||||
|
@ -67,6 +68,24 @@ public class SearchResponse implements ActionResponse, ToXContent {
|
|||
this.shardFailures = shardFailures;
|
||||
}
|
||||
|
||||
public RestStatus status() {
|
||||
if (shardFailures.length == 0) {
|
||||
return RestStatus.OK;
|
||||
}
|
||||
if (successfulShards == 0 && totalShards > 0) {
|
||||
RestStatus status = shardFailures[0].status();
|
||||
if (shardFailures.length > 1) {
|
||||
for (int i = 1; i < shardFailures.length; i++) {
|
||||
if (shardFailures[i].status().getStatus() >= 500) {
|
||||
status = shardFailures[i].status();
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return RestStatus.OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* The search hits.
|
||||
*/
|
||||
|
@ -216,6 +235,7 @@ public class SearchResponse implements ActionResponse, ToXContent {
|
|||
static final XContentBuilderString SUCCESSFUL = new XContentBuilderString("successful");
|
||||
static final XContentBuilderString FAILED = new XContentBuilderString("failed");
|
||||
static final XContentBuilderString FAILURES = new XContentBuilderString("failures");
|
||||
static final XContentBuilderString STATUS = new XContentBuilderString("status");
|
||||
static final XContentBuilderString INDEX = new XContentBuilderString("index");
|
||||
static final XContentBuilderString SHARD = new XContentBuilderString("shard");
|
||||
static final XContentBuilderString REASON = new XContentBuilderString("reason");
|
||||
|
@ -242,6 +262,7 @@ public class SearchResponse implements ActionResponse, ToXContent {
|
|||
builder.field(Fields.INDEX, shardFailure.shard().index());
|
||||
builder.field(Fields.SHARD, shardFailure.shard().shardId());
|
||||
}
|
||||
builder.field(Fields.STATUS, shardFailure.status().getStatus());
|
||||
builder.field(Fields.REASON, shardFailure.reason());
|
||||
builder.endObject();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
|
||||
package org.elasticsearch.action.search;
|
||||
|
||||
import org.elasticsearch.ElasticSearchException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.search.SearchException;
|
||||
import org.elasticsearch.search.SearchShardTarget;
|
||||
|
||||
|
@ -44,6 +46,8 @@ public class ShardSearchFailure implements ShardOperationFailedException {
|
|||
|
||||
private String reason;
|
||||
|
||||
private RestStatus status;
|
||||
|
||||
private ShardSearchFailure() {
|
||||
|
||||
}
|
||||
|
@ -53,6 +57,11 @@ public class ShardSearchFailure implements ShardOperationFailedException {
|
|||
if (actual != null && actual instanceof SearchException) {
|
||||
this.shardTarget = ((SearchException) actual).shard();
|
||||
}
|
||||
if (actual != null && actual instanceof ElasticSearchException) {
|
||||
status = ((ElasticSearchException) t).status();
|
||||
} else {
|
||||
status = RestStatus.INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
this.reason = ExceptionsHelper.detailedMessage(t);
|
||||
}
|
||||
|
||||
|
@ -62,12 +71,16 @@ public class ShardSearchFailure implements ShardOperationFailedException {
|
|||
}
|
||||
|
||||
/**
|
||||
* The search shard target the failure occured on.
|
||||
* The search shard target the failure occurred on.
|
||||
*/
|
||||
@Nullable public SearchShardTarget shard() {
|
||||
return this.shardTarget;
|
||||
}
|
||||
|
||||
public RestStatus status() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The index the search failed on.
|
||||
*/
|
||||
|
@ -110,6 +123,7 @@ public class ShardSearchFailure implements ShardOperationFailedException {
|
|||
shardTarget = readSearchShardTarget(in);
|
||||
}
|
||||
reason = in.readUTF();
|
||||
status = RestStatus.readFrom(in);
|
||||
}
|
||||
|
||||
@Override public void writeTo(StreamOutput out) throws IOException {
|
||||
|
@ -120,5 +134,6 @@ public class ShardSearchFailure implements ShardOperationFailedException {
|
|||
shardTarget.writeTo(out);
|
||||
}
|
||||
out.writeUTF(reason);
|
||||
RestStatus.writeTo(out, status);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
|
||||
package org.elasticsearch.rest;
|
||||
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public enum RestStatus {
|
||||
/**
|
||||
* The client SHOULD continue with its request. This interim response is used to inform the client that the
|
||||
|
@ -477,4 +482,12 @@ public enum RestStatus {
|
|||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static RestStatus readFrom(StreamInput in) throws IOException {
|
||||
return RestStatus.valueOf(in.readUTF());
|
||||
}
|
||||
|
||||
public static void writeTo(StreamOutput out, RestStatus status) throws IOException {
|
||||
out.writeUTF(status.name());
|
||||
}
|
||||
}
|
|
@ -104,7 +104,7 @@ public class RestSearchAction extends BaseRestHandler {
|
|||
builder.startObject();
|
||||
response.toXContent(builder, request);
|
||||
builder.endObject();
|
||||
channel.sendResponse(new XContentRestResponse(request, OK, builder));
|
||||
channel.sendResponse(new XContentRestResponse(request, response.status(), builder));
|
||||
} catch (Exception e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("failed to execute search (building response)", e);
|
||||
|
|
|
@ -27,7 +27,12 @@ import org.elasticsearch.client.Client;
|
|||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestChannel;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.XContentRestResponse;
|
||||
import org.elasticsearch.rest.XContentThrowableRestResponse;
|
||||
import org.elasticsearch.search.Scroll;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -86,7 +91,7 @@ public class RestSearchScrollAction extends BaseRestHandler {
|
|||
builder.startObject();
|
||||
response.toXContent(builder, request);
|
||||
builder.endObject();
|
||||
channel.sendResponse(new XContentRestResponse(request, OK, builder));
|
||||
channel.sendResponse(new XContentRestResponse(request, response.status(), builder));
|
||||
} catch (Exception e) {
|
||||
onFailure(e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue