Main response should not have status 503 when okay (#29045)
The REST status 503 means "I can not handle the request that you sent me." However today we respond to a main request with a 503 when there are certain cluster blocks despite still responding with an actual main response. This is broken, we should respond with a 200 status. This commit removes this silliness.
This commit is contained in:
parent
647d0a1e95
commit
24d10adaab
|
@ -37,11 +37,6 @@ import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.main.MainRequest;
|
import org.elasticsearch.action.main.MainRequest;
|
||||||
import org.elasticsearch.action.main.MainResponse;
|
import org.elasticsearch.action.main.MainResponse;
|
||||||
import org.elasticsearch.action.support.PlainActionFuture;
|
import org.elasticsearch.action.support.PlainActionFuture;
|
||||||
import org.elasticsearch.client.Request;
|
|
||||||
import org.elasticsearch.client.Response;
|
|
||||||
import org.elasticsearch.client.ResponseListener;
|
|
||||||
import org.elasticsearch.client.RestClient;
|
|
||||||
import org.elasticsearch.client.RestHighLevelClient;
|
|
||||||
import org.elasticsearch.cluster.ClusterName;
|
import org.elasticsearch.cluster.ClusterName;
|
||||||
import org.elasticsearch.common.SuppressForbidden;
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
@ -162,7 +157,7 @@ public class CustomRestHighLevelClientTests extends ESTestCase {
|
||||||
ProtocolVersion protocol = new ProtocolVersion("HTTP", 1, 1);
|
ProtocolVersion protocol = new ProtocolVersion("HTTP", 1, 1);
|
||||||
when(mockResponse.getStatusLine()).thenReturn(new BasicStatusLine(protocol, 200, "OK"));
|
when(mockResponse.getStatusLine()).thenReturn(new BasicStatusLine(protocol, 200, "OK"));
|
||||||
|
|
||||||
MainResponse response = new MainResponse(httpHeader.getValue(), Version.CURRENT, ClusterName.DEFAULT, "_na", Build.CURRENT, true);
|
MainResponse response = new MainResponse(httpHeader.getValue(), Version.CURRENT, ClusterName.DEFAULT, "_na", Build.CURRENT);
|
||||||
BytesRef bytesRef = XContentHelper.toXContent(response, XContentType.JSON, false).toBytesRef();
|
BytesRef bytesRef = XContentHelper.toXContent(response, XContentType.JSON, false).toBytesRef();
|
||||||
when(mockResponse.getEntity()).thenReturn(new ByteArrayEntity(bytesRef.bytes, ContentType.APPLICATION_JSON));
|
when(mockResponse.getEntity()).thenReturn(new ByteArrayEntity(bytesRef.bytes, ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class RestHighLevelClientTests extends ESTestCase {
|
||||||
public void testInfo() throws IOException {
|
public void testInfo() throws IOException {
|
||||||
Header[] headers = randomHeaders(random(), "Header");
|
Header[] headers = randomHeaders(random(), "Header");
|
||||||
MainResponse testInfo = new MainResponse("nodeName", Version.CURRENT, new ClusterName("clusterName"), "clusterUuid",
|
MainResponse testInfo = new MainResponse("nodeName", Version.CURRENT, new ClusterName("clusterName"), "clusterUuid",
|
||||||
Build.CURRENT, true);
|
Build.CURRENT);
|
||||||
mockResponse(testInfo);
|
mockResponse(testInfo);
|
||||||
MainResponse receivedInfo = restHighLevelClient.info(headers);
|
MainResponse receivedInfo = restHighLevelClient.info(headers);
|
||||||
assertEquals(testInfo, receivedInfo);
|
assertEquals(testInfo, receivedInfo);
|
||||||
|
|
|
@ -52,7 +52,6 @@ public class MainDocumentationIT extends ESRestHighLevelClientTestCase {
|
||||||
//tag::main-execute
|
//tag::main-execute
|
||||||
MainResponse response = client.info();
|
MainResponse response = client.info();
|
||||||
//end::main-execute
|
//end::main-execute
|
||||||
assertTrue(response.isAvailable());
|
|
||||||
//tag::main-response
|
//tag::main-response
|
||||||
ClusterName clusterName = response.getClusterName(); // <1>
|
ClusterName clusterName = response.getClusterName(); // <1>
|
||||||
String clusterUuid = response.getClusterUuid(); // <2>
|
String clusterUuid = response.getClusterUuid(); // <2>
|
||||||
|
|
|
@ -41,18 +41,16 @@ public class MainResponse extends ActionResponse implements ToXContentObject {
|
||||||
private ClusterName clusterName;
|
private ClusterName clusterName;
|
||||||
private String clusterUuid;
|
private String clusterUuid;
|
||||||
private Build build;
|
private Build build;
|
||||||
boolean available;
|
|
||||||
|
|
||||||
MainResponse() {
|
MainResponse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainResponse(String nodeName, Version version, ClusterName clusterName, String clusterUuid, Build build, boolean available) {
|
public MainResponse(String nodeName, Version version, ClusterName clusterName, String clusterUuid, Build build) {
|
||||||
this.nodeName = nodeName;
|
this.nodeName = nodeName;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.clusterName = clusterName;
|
this.clusterName = clusterName;
|
||||||
this.clusterUuid = clusterUuid;
|
this.clusterUuid = clusterUuid;
|
||||||
this.build = build;
|
this.build = build;
|
||||||
this.available = available;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNodeName() {
|
public String getNodeName() {
|
||||||
|
@ -75,10 +73,6 @@ public class MainResponse extends ActionResponse implements ToXContentObject {
|
||||||
return build;
|
return build;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAvailable() {
|
|
||||||
return available;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
|
@ -87,7 +81,9 @@ public class MainResponse extends ActionResponse implements ToXContentObject {
|
||||||
clusterName.writeTo(out);
|
clusterName.writeTo(out);
|
||||||
out.writeString(clusterUuid);
|
out.writeString(clusterUuid);
|
||||||
Build.writeBuild(build, out);
|
Build.writeBuild(build, out);
|
||||||
out.writeBoolean(available);
|
if (out.getVersion().before(Version.V_7_0_0_alpha1)) {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,7 +94,9 @@ public class MainResponse extends ActionResponse implements ToXContentObject {
|
||||||
clusterName = new ClusterName(in);
|
clusterName = new ClusterName(in);
|
||||||
clusterUuid = in.readString();
|
clusterUuid = in.readString();
|
||||||
build = Build.readBuild(in);
|
build = Build.readBuild(in);
|
||||||
available = in.readBoolean();
|
if (in.getVersion().before(Version.V_7_0_0_alpha1)) {
|
||||||
|
in.readBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -133,7 +131,6 @@ public class MainResponse extends ActionResponse implements ToXContentObject {
|
||||||
response.build = new Build((String) value.get("build_hash"), (String) value.get("build_date"),
|
response.build = new Build((String) value.get("build_hash"), (String) value.get("build_date"),
|
||||||
(boolean) value.get("build_snapshot"));
|
(boolean) value.get("build_snapshot"));
|
||||||
response.version = Version.fromString((String) value.get("number"));
|
response.version = Version.fromString((String) value.get("number"));
|
||||||
response.available = true;
|
|
||||||
}, (parser, context) -> parser.map(), new ParseField("version"));
|
}, (parser, context) -> parser.map(), new ParseField("version"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,12 +151,11 @@ public class MainResponse extends ActionResponse implements ToXContentObject {
|
||||||
Objects.equals(version, other.version) &&
|
Objects.equals(version, other.version) &&
|
||||||
Objects.equals(clusterUuid, other.clusterUuid) &&
|
Objects.equals(clusterUuid, other.clusterUuid) &&
|
||||||
Objects.equals(build, other.build) &&
|
Objects.equals(build, other.build) &&
|
||||||
Objects.equals(available, other.available) &&
|
|
||||||
Objects.equals(clusterName, other.clusterName);
|
Objects.equals(clusterName, other.clusterName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(nodeName, version, clusterUuid, build, clusterName, available);
|
return Objects.hash(nodeName, version, clusterUuid, build, clusterName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,6 @@ public class TransportMainAction extends HandledTransportAction<MainRequest, Mai
|
||||||
final boolean available = clusterState.getBlocks().hasGlobalBlock(RestStatus.SERVICE_UNAVAILABLE) == false;
|
final boolean available = clusterState.getBlocks().hasGlobalBlock(RestStatus.SERVICE_UNAVAILABLE) == false;
|
||||||
listener.onResponse(
|
listener.onResponse(
|
||||||
new MainResponse(Node.NODE_NAME_SETTING.get(settings), Version.CURRENT, clusterState.getClusterName(),
|
new MainResponse(Node.NODE_NAME_SETTING.get(settings), Version.CURRENT, clusterState.getClusterName(),
|
||||||
clusterState.metaData().clusterUUID(), Build.CURRENT, available));
|
clusterState.metaData().clusterUUID(), Build.CURRENT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,13 +60,11 @@ public class RestMainAction extends BaseRestHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
static BytesRestResponse convertMainResponse(MainResponse response, RestRequest request, XContentBuilder builder) throws IOException {
|
static BytesRestResponse convertMainResponse(MainResponse response, RestRequest request, XContentBuilder builder) throws IOException {
|
||||||
RestStatus status = response.isAvailable() ? RestStatus.OK : RestStatus.SERVICE_UNAVAILABLE;
|
|
||||||
|
|
||||||
// Default to pretty printing, but allow ?pretty=false to disable
|
// Default to pretty printing, but allow ?pretty=false to disable
|
||||||
if (request.hasParam("pretty") == false) {
|
if (request.hasParam("pretty") == false) {
|
||||||
builder.prettyPrint().lfAtEnd();
|
builder.prettyPrint().lfAtEnd();
|
||||||
}
|
}
|
||||||
response.toXContent(builder, request);
|
response.toXContent(builder, request);
|
||||||
return new BytesRestResponse(status, builder);
|
return new BytesRestResponse(RestStatus.OK, builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,8 @@ public class MainActionTests extends ESTestCase {
|
||||||
final ClusterService clusterService = mock(ClusterService.class);
|
final ClusterService clusterService = mock(ClusterService.class);
|
||||||
final ClusterName clusterName = new ClusterName("elasticsearch");
|
final ClusterName clusterName = new ClusterName("elasticsearch");
|
||||||
final Settings settings = Settings.builder().put("node.name", "my-node").build();
|
final Settings settings = Settings.builder().put("node.name", "my-node").build();
|
||||||
final boolean available = randomBoolean();
|
|
||||||
ClusterBlocks blocks;
|
ClusterBlocks blocks;
|
||||||
if (available) {
|
if (randomBoolean()) {
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
blocks = ClusterBlocks.EMPTY_CLUSTER_BLOCK;
|
blocks = ClusterBlocks.EMPTY_CLUSTER_BLOCK;
|
||||||
} else {
|
} else {
|
||||||
|
@ -86,7 +85,6 @@ public class MainActionTests extends ESTestCase {
|
||||||
});
|
});
|
||||||
|
|
||||||
assertNotNull(responseRef.get());
|
assertNotNull(responseRef.get());
|
||||||
assertEquals(available, responseRef.get().isAvailable());
|
|
||||||
verify(clusterService, times(1)).state();
|
verify(clusterService, times(1)).state();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class MainResponseTests extends AbstractStreamableXContentTestCase<MainRe
|
||||||
String nodeName = randomAlphaOfLength(10);
|
String nodeName = randomAlphaOfLength(10);
|
||||||
Build build = new Build(randomAlphaOfLength(8), new Date(randomNonNegativeLong()).toString(), randomBoolean());
|
Build build = new Build(randomAlphaOfLength(8), new Date(randomNonNegativeLong()).toString(), randomBoolean());
|
||||||
Version version = VersionUtils.randomVersion(random());
|
Version version = VersionUtils.randomVersion(random());
|
||||||
return new MainResponse(nodeName, version, clusterName, clusterUuid , build, true);
|
return new MainResponse(nodeName, version, clusterName, clusterUuid , build);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,7 +58,7 @@ public class MainResponseTests extends AbstractStreamableXContentTestCase<MainRe
|
||||||
String clusterUUID = randomAlphaOfLengthBetween(10, 20);
|
String clusterUUID = randomAlphaOfLengthBetween(10, 20);
|
||||||
Build build = new Build(Build.CURRENT.shortHash(), Build.CURRENT.date(), Build.CURRENT.isSnapshot());
|
Build build = new Build(Build.CURRENT.shortHash(), Build.CURRENT.date(), Build.CURRENT.isSnapshot());
|
||||||
Version version = Version.CURRENT;
|
Version version = Version.CURRENT;
|
||||||
MainResponse response = new MainResponse("nodeName", version, new ClusterName("clusterName"), clusterUUID, build, true);
|
MainResponse response = new MainResponse("nodeName", version, new ClusterName("clusterName"), clusterUUID, build);
|
||||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||||
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||||
assertEquals("{"
|
assertEquals("{"
|
||||||
|
@ -80,12 +80,11 @@ public class MainResponseTests extends AbstractStreamableXContentTestCase<MainRe
|
||||||
@Override
|
@Override
|
||||||
protected MainResponse mutateInstance(MainResponse mutateInstance) {
|
protected MainResponse mutateInstance(MainResponse mutateInstance) {
|
||||||
String clusterUuid = mutateInstance.getClusterUuid();
|
String clusterUuid = mutateInstance.getClusterUuid();
|
||||||
boolean available = mutateInstance.isAvailable();
|
|
||||||
Build build = mutateInstance.getBuild();
|
Build build = mutateInstance.getBuild();
|
||||||
Version version = mutateInstance.getVersion();
|
Version version = mutateInstance.getVersion();
|
||||||
String nodeName = mutateInstance.getNodeName();
|
String nodeName = mutateInstance.getNodeName();
|
||||||
ClusterName clusterName = mutateInstance.getClusterName();
|
ClusterName clusterName = mutateInstance.getClusterName();
|
||||||
switch (randomIntBetween(0, 5)) {
|
switch (randomIntBetween(0, 4)) {
|
||||||
case 0:
|
case 0:
|
||||||
clusterUuid = clusterUuid + randomAlphaOfLength(5);
|
clusterUuid = clusterUuid + randomAlphaOfLength(5);
|
||||||
break;
|
break;
|
||||||
|
@ -93,19 +92,16 @@ public class MainResponseTests extends AbstractStreamableXContentTestCase<MainRe
|
||||||
nodeName = nodeName + randomAlphaOfLength(5);
|
nodeName = nodeName + randomAlphaOfLength(5);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
available = !available;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
// toggle the snapshot flag of the original Build parameter
|
// toggle the snapshot flag of the original Build parameter
|
||||||
build = new Build(build.shortHash(), build.date(), !build.isSnapshot());
|
build = new Build(build.shortHash(), build.date(), !build.isSnapshot());
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 3:
|
||||||
version = randomValueOtherThan(version, () -> VersionUtils.randomVersion(random()));
|
version = randomValueOtherThan(version, () -> VersionUtils.randomVersion(random()));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 4:
|
||||||
clusterName = new ClusterName(clusterName + randomAlphaOfLength(5));
|
clusterName = new ClusterName(clusterName + randomAlphaOfLength(5));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return new MainResponse(nodeName, version, clusterName, clusterUuid, build, available);
|
return new MainResponse(nodeName, version, clusterName, clusterUuid, build);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.test.rest.FakeRestRequest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
|
|
||||||
public class RestMainActionTests extends ESTestCase {
|
public class RestMainActionTests extends ESTestCase {
|
||||||
|
@ -44,12 +45,10 @@ public class RestMainActionTests extends ESTestCase {
|
||||||
final String nodeName = "node1";
|
final String nodeName = "node1";
|
||||||
final ClusterName clusterName = new ClusterName("cluster1");
|
final ClusterName clusterName = new ClusterName("cluster1");
|
||||||
final String clusterUUID = randomAlphaOfLengthBetween(10, 20);
|
final String clusterUUID = randomAlphaOfLengthBetween(10, 20);
|
||||||
final boolean available = randomBoolean();
|
|
||||||
final RestStatus expectedStatus = available ? RestStatus.OK : RestStatus.SERVICE_UNAVAILABLE;
|
|
||||||
final Version version = Version.CURRENT;
|
final Version version = Version.CURRENT;
|
||||||
final Build build = Build.CURRENT;
|
final Build build = Build.CURRENT;
|
||||||
|
|
||||||
final MainResponse mainResponse = new MainResponse(nodeName, version, clusterName, clusterUUID, build, available);
|
final MainResponse mainResponse = new MainResponse(nodeName, version, clusterName, clusterUUID, build);
|
||||||
XContentBuilder builder = JsonXContent.contentBuilder();
|
XContentBuilder builder = JsonXContent.contentBuilder();
|
||||||
RestRequest restRequest = new FakeRestRequest() {
|
RestRequest restRequest = new FakeRestRequest() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,7 +59,7 @@ public class RestMainActionTests extends ESTestCase {
|
||||||
|
|
||||||
BytesRestResponse response = RestMainAction.convertMainResponse(mainResponse, restRequest, builder);
|
BytesRestResponse response = RestMainAction.convertMainResponse(mainResponse, restRequest, builder);
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(expectedStatus, response.status());
|
assertThat(response.status(), equalTo(RestStatus.OK));
|
||||||
|
|
||||||
// the empty responses are handled in the HTTP layer so we do
|
// the empty responses are handled in the HTTP layer so we do
|
||||||
// not assert on them here
|
// not assert on them here
|
||||||
|
@ -70,13 +69,11 @@ public class RestMainActionTests extends ESTestCase {
|
||||||
final String nodeName = "node1";
|
final String nodeName = "node1";
|
||||||
final ClusterName clusterName = new ClusterName("cluster1");
|
final ClusterName clusterName = new ClusterName("cluster1");
|
||||||
final String clusterUUID = randomAlphaOfLengthBetween(10, 20);
|
final String clusterUUID = randomAlphaOfLengthBetween(10, 20);
|
||||||
final boolean available = randomBoolean();
|
|
||||||
final RestStatus expectedStatus = available ? RestStatus.OK : RestStatus.SERVICE_UNAVAILABLE;
|
|
||||||
final Version version = Version.CURRENT;
|
final Version version = Version.CURRENT;
|
||||||
final Build build = Build.CURRENT;
|
final Build build = Build.CURRENT;
|
||||||
final boolean prettyPrint = randomBoolean();
|
final boolean prettyPrint = randomBoolean();
|
||||||
|
|
||||||
final MainResponse mainResponse = new MainResponse(nodeName, version, clusterName, clusterUUID, build, available);
|
final MainResponse mainResponse = new MainResponse(nodeName, version, clusterName, clusterUUID, build);
|
||||||
XContentBuilder builder = JsonXContent.contentBuilder();
|
XContentBuilder builder = JsonXContent.contentBuilder();
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
|
@ -87,7 +84,7 @@ public class RestMainActionTests extends ESTestCase {
|
||||||
|
|
||||||
BytesRestResponse response = RestMainAction.convertMainResponse(mainResponse, restRequest, builder);
|
BytesRestResponse response = RestMainAction.convertMainResponse(mainResponse, restRequest, builder);
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(expectedStatus, response.status());
|
assertThat(response.status(), equalTo(RestStatus.OK));
|
||||||
assertThat(response.content().length(), greaterThan(0));
|
assertThat(response.content().length(), greaterThan(0));
|
||||||
|
|
||||||
XContentBuilder responseBuilder = JsonXContent.contentBuilder();
|
XContentBuilder responseBuilder = JsonXContent.contentBuilder();
|
||||||
|
|
Loading…
Reference in New Issue