Adds explain lifecycle API to the Rest Client (#32606)
This commit is contained in:
parent
2fc3f1d04c
commit
5ff4f9347f
|
@ -20,6 +20,8 @@
|
||||||
package org.elasticsearch.client;
|
package org.elasticsearch.client;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleResponse;
|
||||||
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
||||||
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse;
|
||||||
|
|
||||||
|
@ -62,4 +64,32 @@ public class IndexLifecycleClient {
|
||||||
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::setIndexLifecyclePolicy, options,
|
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::setIndexLifecyclePolicy, options,
|
||||||
SetIndexLifecyclePolicyResponse::fromXContent, listener, emptySet());
|
SetIndexLifecyclePolicyResponse::fromXContent, listener, emptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Explain the lifecycle state for an index
|
||||||
|
* See <a href="https://fix-me-when-we-have-docs.com">
|
||||||
|
* the docs</a> for more.
|
||||||
|
* @param request the request
|
||||||
|
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||||
|
* @return the response
|
||||||
|
* @throws IOException in case there is a problem sending the request or parsing back the response
|
||||||
|
*/
|
||||||
|
public ExplainLifecycleResponse explainLifecycle(ExplainLifecycleRequest request,RequestOptions options) throws IOException {
|
||||||
|
return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::explainLifecycle, options,
|
||||||
|
ExplainLifecycleResponse::fromXContent, emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously explain the lifecycle state for an index
|
||||||
|
* See <a href="https://fix-me-when-we-have-docs.com">
|
||||||
|
* the docs</a> for more.
|
||||||
|
* @param request the request
|
||||||
|
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
|
||||||
|
* @param listener the listener to be notified upon request completion
|
||||||
|
*/
|
||||||
|
public void explainLifecycleAsync(ExplainLifecycleRequest request, RequestOptions options,
|
||||||
|
ActionListener<ExplainLifecycleResponse> listener) {
|
||||||
|
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::explainLifecycle, options,
|
||||||
|
ExplainLifecycleResponse::fromXContent, listener, emptySet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ import org.elasticsearch.index.rankeval.RankEvalRequest;
|
||||||
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
|
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
|
||||||
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
|
import org.elasticsearch.protocol.xpack.license.GetLicenseRequest;
|
||||||
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
|
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
|
||||||
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
||||||
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
|
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
|
||||||
import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
|
import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
|
||||||
|
@ -1169,6 +1170,20 @@ final class RequestConverters {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Request explainLifecycle(ExplainLifecycleRequest explainLifecycleRequest) {
|
||||||
|
String[] indices = explainLifecycleRequest.indices() == null ? Strings.EMPTY_ARRAY : explainLifecycleRequest.indices();
|
||||||
|
Request request = new Request(HttpGet.METHOD_NAME,
|
||||||
|
new EndpointBuilder()
|
||||||
|
.addCommaSeparatedPathParts(indices)
|
||||||
|
.addPathPartAsIs("_ilm")
|
||||||
|
.addPathPartAsIs("explain")
|
||||||
|
.build());
|
||||||
|
Params params = new Params(request);
|
||||||
|
params.withIndicesOptions(explainLifecycleRequest.indicesOptions());
|
||||||
|
params.withMasterTimeout(explainLifecycleRequest.masterNodeTimeout());
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
static Request putLicense(PutLicenseRequest putLicenseRequest) {
|
static Request putLicense(PutLicenseRequest putLicenseRequest) {
|
||||||
String endpoint = new EndpointBuilder()
|
String endpoint = new EndpointBuilder()
|
||||||
.addPathPartAsIs("_xpack")
|
.addPathPartAsIs("_xpack")
|
||||||
|
|
|
@ -25,9 +25,14 @@ import org.apache.http.nio.entity.NStringEntity;
|
||||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
|
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleResponse;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.IndexLifecycleExplainResponse;
|
||||||
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
||||||
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
@ -100,4 +105,95 @@ public class IndexLifecycleIT extends ESRestHighLevelClientTestCase {
|
||||||
assertThat(settingsResponse.getSetting("foo", "index.lifecycle.name"), equalTo(policy));
|
assertThat(settingsResponse.getSetting("foo", "index.lifecycle.name"), equalTo(policy));
|
||||||
assertThat(settingsResponse.getSetting("baz", "index.lifecycle.name"), equalTo(policy));
|
assertThat(settingsResponse.getSetting("baz", "index.lifecycle.name"), equalTo(policy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExplainLifecycle() throws Exception {
|
||||||
|
String policy = randomAlphaOfLength(10);
|
||||||
|
|
||||||
|
// TODO: NORELEASE convert this to using the high level client once there are APIs for it
|
||||||
|
String jsonString = "{\n" +
|
||||||
|
" \"policy\": {\n" +
|
||||||
|
" \"type\": \"timeseries\",\n" +
|
||||||
|
" \"phases\": {\n" +
|
||||||
|
" \"hot\": {\n" +
|
||||||
|
" \"actions\": {\n" +
|
||||||
|
" \"rollover\": {\n" +
|
||||||
|
" \"max_age\": \"50d\"\n" +
|
||||||
|
" } \n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"warm\": {\n" +
|
||||||
|
" \"after\": \"1000s\",\n" +
|
||||||
|
" \"actions\": {\n" +
|
||||||
|
" \"allocate\": {\n" +
|
||||||
|
" \"require\": { \"_name\": \"node-1\" },\n" +
|
||||||
|
" \"include\": {},\n" +
|
||||||
|
" \"exclude\": {}\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"shrink\": {\n" +
|
||||||
|
" \"number_of_shards\": 1\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"forcemerge\": {\n" +
|
||||||
|
" \"max_num_segments\": 1000\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"cold\": {\n" +
|
||||||
|
" \"after\": \"2000s\",\n" +
|
||||||
|
" \"actions\": {\n" +
|
||||||
|
" \"replicas\": {\n" +
|
||||||
|
" \"number_of_replicas\": 0\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"delete\": {\n" +
|
||||||
|
" \"after\": \"3000s\",\n" +
|
||||||
|
" \"actions\": {\n" +
|
||||||
|
" \"delete\": {}\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);
|
||||||
|
Request request = new Request("PUT", "/_ilm/" + policy);
|
||||||
|
request.setEntity(entity);
|
||||||
|
client().performRequest(request);
|
||||||
|
|
||||||
|
createIndex("foo", Settings.builder().put("index.lifecycle.name", policy).build());
|
||||||
|
createIndex("baz", Settings.builder().put("index.lifecycle.name", policy).build());
|
||||||
|
createIndex("squash", Settings.EMPTY);
|
||||||
|
assertBusy(() -> {
|
||||||
|
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices("foo", "baz");
|
||||||
|
GetSettingsResponse settingsResponse = highLevelClient().indices().getSettings(getSettingsRequest, RequestOptions.DEFAULT);
|
||||||
|
assertThat(settingsResponse.getSetting("foo", "index.lifecycle.name"), equalTo(policy));
|
||||||
|
assertThat(settingsResponse.getSetting("baz", "index.lifecycle.name"), equalTo(policy));
|
||||||
|
assertThat(settingsResponse.getSetting("foo", "index.lifecycle.phase"), equalTo("hot"));
|
||||||
|
assertThat(settingsResponse.getSetting("baz", "index.lifecycle.phase"), equalTo("hot"));
|
||||||
|
});
|
||||||
|
|
||||||
|
ExplainLifecycleRequest req = new ExplainLifecycleRequest();
|
||||||
|
req.indices("foo", "baz", "squash");
|
||||||
|
ExplainLifecycleResponse response = execute(req, highLevelClient().indexLifecycle()::explainLifecycle,
|
||||||
|
highLevelClient().indexLifecycle()::explainLifecycleAsync);
|
||||||
|
Map<String, IndexLifecycleExplainResponse> indexResponses = response.getIndexResponses();
|
||||||
|
assertEquals(3, indexResponses.size());
|
||||||
|
IndexLifecycleExplainResponse fooResponse = indexResponses.get("foo");
|
||||||
|
assertNotNull(fooResponse);
|
||||||
|
assertTrue(fooResponse.managedByILM());
|
||||||
|
assertEquals("foo", fooResponse.getIndex());
|
||||||
|
assertEquals("hot", fooResponse.getPhase());
|
||||||
|
assertEquals("rollover", fooResponse.getAction());
|
||||||
|
assertEquals("attempt_rollover", fooResponse.getStep());
|
||||||
|
IndexLifecycleExplainResponse bazResponse = indexResponses.get("baz");
|
||||||
|
assertNotNull(bazResponse);
|
||||||
|
assertTrue(bazResponse.managedByILM());
|
||||||
|
assertEquals("baz", bazResponse.getIndex());
|
||||||
|
assertEquals("hot", bazResponse.getPhase());
|
||||||
|
assertEquals("rollover", bazResponse.getAction());
|
||||||
|
assertEquals("attempt_rollover", bazResponse.getStep());
|
||||||
|
IndexLifecycleExplainResponse squashResponse = indexResponses.get("squash");
|
||||||
|
assertNotNull(squashResponse);
|
||||||
|
assertFalse(squashResponse.managedByILM());
|
||||||
|
assertEquals("squash", squashResponse.getIndex());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ import org.elasticsearch.index.rankeval.RankEvalSpec;
|
||||||
import org.elasticsearch.index.rankeval.RatedRequest;
|
import org.elasticsearch.index.rankeval.RatedRequest;
|
||||||
import org.elasticsearch.index.rankeval.RestRankEvalAction;
|
import org.elasticsearch.index.rankeval.RestRankEvalAction;
|
||||||
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
|
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
|
||||||
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest;
|
||||||
import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
|
import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
|
||||||
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
|
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
|
||||||
|
@ -2601,6 +2602,21 @@ public class RequestConvertersTests extends ESTestCase {
|
||||||
assertThat(request.getParameters(), equalTo(expectedParams));
|
assertThat(request.getParameters(), equalTo(expectedParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExplainLifecycle() throws Exception {
|
||||||
|
ExplainLifecycleRequest req = new ExplainLifecycleRequest();
|
||||||
|
String[] indices = rarely() ? null : randomIndicesNames(0, 10);
|
||||||
|
req.indices(indices);
|
||||||
|
Map<String, String> expectedParams = new HashMap<>();
|
||||||
|
setRandomMasterTimeout(req, expectedParams);
|
||||||
|
setRandomIndicesOptions(req::indicesOptions, req::indicesOptions, expectedParams);
|
||||||
|
|
||||||
|
Request request = RequestConverters.explainLifecycle(req);
|
||||||
|
assertThat(request.getMethod(), equalTo(HttpGet.METHOD_NAME));
|
||||||
|
String idxString = Strings.arrayToCommaDelimitedString(indices);
|
||||||
|
assertThat(request.getEndpoint(), equalTo("/" + (idxString.isEmpty() ? "" : (idxString + "/")) + "_ilm/explain"));
|
||||||
|
assertThat(request.getParameters(), equalTo(expectedParams));
|
||||||
|
}
|
||||||
|
|
||||||
public void testXPackDeleteWatch() {
|
public void testXPackDeleteWatch() {
|
||||||
DeleteWatchRequest deleteWatchRequest = new DeleteWatchRequest();
|
DeleteWatchRequest deleteWatchRequest = new DeleteWatchRequest();
|
||||||
String watchId = randomAlphaOfLength(10);
|
String watchId = randomAlphaOfLength(10);
|
||||||
|
|
|
@ -7,21 +7,9 @@
|
||||||
package org.elasticsearch.xpack.core.indexlifecycle.action;
|
package org.elasticsearch.xpack.core.indexlifecycle.action;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleResponse;
|
||||||
import org.elasticsearch.action.ActionResponse;
|
|
||||||
import org.elasticsearch.action.support.master.info.ClusterInfoRequest;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
public class ExplainLifecycleAction extends Action<ExplainLifecycleResponse> {
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class ExplainLifecycleAction extends Action<ExplainLifecycleAction.Response> {
|
|
||||||
public static final ExplainLifecycleAction INSTANCE = new ExplainLifecycleAction();
|
public static final ExplainLifecycleAction INSTANCE = new ExplainLifecycleAction();
|
||||||
public static final String NAME = "indices:admin/ilm/explain";
|
public static final String NAME = "indices:admin/ilm/explain";
|
||||||
|
|
||||||
|
@ -30,107 +18,8 @@ public class ExplainLifecycleAction extends Action<ExplainLifecycleAction.Respon
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response newResponse() {
|
public ExplainLifecycleResponse newResponse() {
|
||||||
return new Response();
|
return new ExplainLifecycleResponse();
|
||||||
}
|
|
||||||
|
|
||||||
public static class Response extends ActionResponse implements ToXContentObject {
|
|
||||||
|
|
||||||
private List<IndexLifecycleExplainResponse> indexResponses;
|
|
||||||
|
|
||||||
public Response() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Response(List<IndexLifecycleExplainResponse> indexResponses) {
|
|
||||||
this.indexResponses = indexResponses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<IndexLifecycleExplainResponse> getIndexResponses() {
|
|
||||||
return indexResponses;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startObject();
|
|
||||||
for (IndexLifecycleExplainResponse indexResponse : indexResponses) {
|
|
||||||
builder.field(indexResponse.getIndex(), indexResponse);
|
|
||||||
}
|
|
||||||
builder.endObject();
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
|
||||||
indexResponses = in.readList(IndexLifecycleExplainResponse::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
|
||||||
out.writeList(indexResponses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(indexResponses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj.getClass() != getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Response other = (Response) obj;
|
|
||||||
return Objects.equals(indexResponses, other.indexResponses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return Strings.toString(this, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Request extends ClusterInfoRequest<Request> {
|
|
||||||
|
|
||||||
public Request() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request(StreamInput in) throws IOException {
|
|
||||||
super(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ActionRequestValidationException validate() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(Arrays.hashCode(indices()), indicesOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (obj.getClass() != getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Request other = (Request) obj;
|
|
||||||
return Objects.deepEquals(indices(), other.indices()) &&
|
|
||||||
Objects.equals(indicesOptions(), other.indicesOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Request [indices()=" + Arrays.toString(indices()) + ", indicesOptions()=" + indicesOptions() + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.xpack.core.indexlifecycle.action;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
|
||||||
import org.elasticsearch.test.AbstractStreamableTestCase;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.DeleteAction;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleType;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.TestLifecycleType;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction.Response;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ExplainLifecycleResponseTests extends AbstractStreamableTestCase<ExplainLifecycleAction.Response> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Response createTestInstance() {
|
|
||||||
List<IndexLifecycleExplainResponse> indexResponses = new ArrayList<>();
|
|
||||||
for (int i = 0; i < randomIntBetween(0, 2); i++) {
|
|
||||||
indexResponses.add(IndexExplainResponseTests.randomIndexExplainResponse());
|
|
||||||
}
|
|
||||||
return new Response(indexResponses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Response createBlankInstance() {
|
|
||||||
return new Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected NamedWriteableRegistry getNamedWriteableRegistry() {
|
|
||||||
return new NamedWriteableRegistry(
|
|
||||||
Arrays.asList(new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new),
|
|
||||||
new NamedWriteableRegistry.Entry(LifecycleType.class, TestLifecycleType.TYPE, in -> TestLifecycleType.INSTANCE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Response mutateInstance(Response response) {
|
|
||||||
List<IndexLifecycleExplainResponse> indexResponses = new ArrayList<>(response.getIndexResponses());
|
|
||||||
if (indexResponses.size() > 0) {
|
|
||||||
if (randomBoolean()) {
|
|
||||||
indexResponses.add(IndexExplainResponseTests.randomIndexExplainResponse());
|
|
||||||
} else {
|
|
||||||
indexResponses.remove(indexResponses.size() - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
indexResponses.add(IndexExplainResponseTests.randomIndexExplainResponse());
|
|
||||||
}
|
|
||||||
return new Response(indexResponses);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,6 +10,7 @@ import org.elasticsearch.action.support.IndicesOptions;
|
||||||
import org.elasticsearch.client.node.NodeClient;
|
import org.elasticsearch.client.node.NodeClient;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
|
||||||
import org.elasticsearch.rest.BaseRestHandler;
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
@ -33,9 +34,10 @@ public class RestExplainLifecycleAction extends BaseRestHandler {
|
||||||
@Override
|
@Override
|
||||||
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
|
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
|
||||||
String[] indexes = Strings.splitStringByCommaToArray(restRequest.param("index"));
|
String[] indexes = Strings.splitStringByCommaToArray(restRequest.param("index"));
|
||||||
ExplainLifecycleAction.Request explainLifecycleRequest = new ExplainLifecycleAction.Request();
|
ExplainLifecycleRequest explainLifecycleRequest = new ExplainLifecycleRequest();
|
||||||
explainLifecycleRequest.indices(indexes);
|
explainLifecycleRequest.indices(indexes);
|
||||||
explainLifecycleRequest.indicesOptions(IndicesOptions.fromRequest(restRequest, IndicesOptions.strictExpandOpen()));
|
explainLifecycleRequest.indicesOptions(IndicesOptions.fromRequest(restRequest, IndicesOptions.strictExpandOpen()));
|
||||||
|
explainLifecycleRequest.masterNodeTimeout(restRequest.param("master_timeout"));
|
||||||
|
|
||||||
return channel -> client.execute(ExplainLifecycleAction.INSTANCE, explainLifecycleRequest, new RestToXContentListener<>(channel));
|
return channel -> client.execute(ExplainLifecycleAction.INSTANCE, explainLifecycleRequest, new RestToXContentListener<>(channel));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,30 +19,30 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleRequest;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.ExplainLifecycleResponse;
|
||||||
|
import org.elasticsearch.protocol.xpack.indexlifecycle.IndexLifecycleExplainResponse;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
|
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction;
|
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction.Request;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction.Response;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.action.IndexLifecycleExplainResponse;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TransportExplainLifecycleAction
|
public class TransportExplainLifecycleAction
|
||||||
extends TransportClusterInfoAction<ExplainLifecycleAction.Request, ExplainLifecycleAction.Response> {
|
extends TransportClusterInfoAction<ExplainLifecycleRequest, ExplainLifecycleResponse> {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportExplainLifecycleAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
public TransportExplainLifecycleAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||||
ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
|
ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||||
super(settings, ExplainLifecycleAction.NAME, transportService, clusterService, threadPool, actionFilters,
|
super(settings, ExplainLifecycleAction.NAME, transportService, clusterService, threadPool, actionFilters,
|
||||||
ExplainLifecycleAction.Request::new, indexNameExpressionResolver);
|
ExplainLifecycleRequest::new, indexNameExpressionResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Response newResponse() {
|
protected ExplainLifecycleResponse newResponse() {
|
||||||
return new ExplainLifecycleAction.Response();
|
return new ExplainLifecycleResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,14 +52,15 @@ public class TransportExplainLifecycleAction
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ClusterBlockException checkBlock(ExplainLifecycleAction.Request request, ClusterState state) {
|
protected ClusterBlockException checkBlock(ExplainLifecycleRequest request, ClusterState state) {
|
||||||
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ,
|
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ,
|
||||||
indexNameExpressionResolver.concreteIndexNames(state, request));
|
indexNameExpressionResolver.concreteIndexNames(state, request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doMasterOperation(Request request, String[] concreteIndices, ClusterState state, ActionListener<Response> listener) {
|
protected void doMasterOperation(ExplainLifecycleRequest request, String[] concreteIndices, ClusterState state,
|
||||||
List<IndexLifecycleExplainResponse> indexReponses = new ArrayList<>();
|
ActionListener<ExplainLifecycleResponse> listener) {
|
||||||
|
Map<String, IndexLifecycleExplainResponse> indexReponses = new HashMap<>();
|
||||||
for (String index : concreteIndices) {
|
for (String index : concreteIndices) {
|
||||||
IndexMetaData idxMetadata = state.metaData().index(index);
|
IndexMetaData idxMetadata = state.metaData().index(index);
|
||||||
Settings idxSettings = idxMetadata.getSettings();
|
Settings idxSettings = idxMetadata.getSettings();
|
||||||
|
@ -80,9 +81,9 @@ public class TransportExplainLifecycleAction
|
||||||
} else {
|
} else {
|
||||||
indexResponse = IndexLifecycleExplainResponse.newUnmanagedIndexResponse(index);
|
indexResponse = IndexLifecycleExplainResponse.newUnmanagedIndexResponse(index);
|
||||||
}
|
}
|
||||||
indexReponses.add(indexResponse);
|
indexReponses.put(indexResponse.getIndex(), indexResponse);
|
||||||
}
|
}
|
||||||
listener.onResponse(new ExplainLifecycleAction.Response(indexReponses));
|
listener.onResponse(new ExplainLifecycleResponse(indexReponses));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.elasticsearch.xpack.core.indexlifecycle.MockAction;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.MockStep;
|
import org.elasticsearch.xpack.core.indexlifecycle.MockStep;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
|
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.RandomStepInfo;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.Step;
|
import org.elasticsearch.xpack.core.indexlifecycle.Step;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.TerminalPolicyStep;
|
import org.elasticsearch.xpack.core.indexlifecycle.TerminalPolicyStep;
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.elasticsearch.xpack.core.indexlifecycle.MockAction;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.MockStep;
|
import org.elasticsearch.xpack.core.indexlifecycle.MockStep;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
|
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.RandomStepInfo;
|
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.Step;
|
import org.elasticsearch.xpack.core.indexlifecycle.Step;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
package org.elasticsearch.xpack.indexlifecycle;
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
@ -107,18 +107,18 @@ teardown:
|
||||||
ilm.explain_lifecycle:
|
ilm.explain_lifecycle:
|
||||||
index: "my_index"
|
index: "my_index"
|
||||||
|
|
||||||
- is_true: my_index.managed
|
- is_true: indices.my_index.managed
|
||||||
- match: { my_index.index: "my_index" }
|
- match: { indices.my_index.index: "my_index" }
|
||||||
- match: { my_index.policy: "my_moveable_timeseries_lifecycle" }
|
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
|
||||||
- match: { my_index.phase: "new" }
|
- match: { indices.my_index.phase: "new" }
|
||||||
- match: { my_index.action: "after" }
|
- match: { indices.my_index.action: "after" }
|
||||||
- match: { my_index.step: "after" }
|
- match: { indices.my_index.step: "after" }
|
||||||
- is_false: my_index.failed_step
|
- is_false: indices.my_index.failed_step
|
||||||
- is_false: my_index.step_info
|
- is_false: indices.my_index.step_info
|
||||||
|
|
||||||
- is_false: my_index2
|
- is_false: indices.my_index2
|
||||||
- is_false: another_index
|
- is_false: indices.another_index
|
||||||
- is_false: unmanaged_index
|
- is_false: indices.unmanaged_index
|
||||||
|
|
||||||
---
|
---
|
||||||
"Test Wildcard Index Lifecycle Explain":
|
"Test Wildcard Index Lifecycle Explain":
|
||||||
|
@ -128,26 +128,26 @@ teardown:
|
||||||
ilm.explain_lifecycle:
|
ilm.explain_lifecycle:
|
||||||
index: "my_*"
|
index: "my_*"
|
||||||
|
|
||||||
- is_true: my_index.managed
|
- is_true: indices.my_index.managed
|
||||||
- match: { my_index.index: "my_index" }
|
- match: { indices.my_index.index: "my_index" }
|
||||||
- match: { my_index.policy: "my_moveable_timeseries_lifecycle" }
|
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
|
||||||
- match: { my_index.phase: "new" }
|
- match: { indices.my_index.phase: "new" }
|
||||||
- match: { my_index.action: "after" }
|
- match: { indices.my_index.action: "after" }
|
||||||
- match: { my_index.step: "after" }
|
- match: { indices.my_index.step: "after" }
|
||||||
- is_false: my_index.failed_step
|
- is_false: indices.my_index.failed_step
|
||||||
- is_false: my_index.step_info
|
- is_false: indices.my_index.step_info
|
||||||
|
|
||||||
- is_true: my_index2.managed
|
- is_true: indices.my_index2.managed
|
||||||
- match: { my_index2.index: "my_index2" }
|
- match: { indices.my_index2.index: "my_index2" }
|
||||||
- match: { my_index2.policy: "my_moveable_timeseries_lifecycle" }
|
- match: { indices.my_index2.policy: "my_moveable_timeseries_lifecycle" }
|
||||||
- match: { my_index2.phase: "new" }
|
- match: { indices.my_index2.phase: "new" }
|
||||||
- match: { my_index2.action: "after" }
|
- match: { indices.my_index2.action: "after" }
|
||||||
- match: { my_index2.step: "after" }
|
- match: { indices.my_index2.step: "after" }
|
||||||
- is_false: my_index2.failed_step
|
- is_false: indices.my_index2.failed_step
|
||||||
- is_false: my_index2.step_info
|
- is_false: indices.my_index2.step_info
|
||||||
|
|
||||||
- is_false: another_index
|
- is_false: indices.another_index
|
||||||
- is_false: unmanaged_index
|
- is_false: indices.unmanaged_index
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -158,41 +158,41 @@ teardown:
|
||||||
ilm.explain_lifecycle:
|
ilm.explain_lifecycle:
|
||||||
index: "*"
|
index: "*"
|
||||||
|
|
||||||
- is_true: my_index.managed
|
- is_true: indices.my_index.managed
|
||||||
- match: { my_index.index: "my_index" }
|
- match: { indices.my_index.index: "my_index" }
|
||||||
- match: { my_index.policy: "my_moveable_timeseries_lifecycle" }
|
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
|
||||||
- match: { my_index.phase: "new" }
|
- match: { indices.my_index.phase: "new" }
|
||||||
- match: { my_index.action: "after" }
|
- match: { indices.my_index.action: "after" }
|
||||||
- match: { my_index.step: "after" }
|
- match: { indices.my_index.step: "after" }
|
||||||
- is_false: my_index.failed_step
|
- is_false: indices.my_index.failed_step
|
||||||
- is_false: my_index.step_info
|
- is_false: indices.my_index.step_info
|
||||||
|
|
||||||
- is_true: my_index2.managed
|
- is_true: indices.my_index2.managed
|
||||||
- match: { my_index2.index: "my_index2" }
|
- match: { indices.my_index2.index: "my_index2" }
|
||||||
- match: { my_index2.policy: "my_moveable_timeseries_lifecycle" }
|
- match: { indices.my_index2.policy: "my_moveable_timeseries_lifecycle" }
|
||||||
- match: { my_index2.phase: "new" }
|
- match: { indices.my_index2.phase: "new" }
|
||||||
- match: { my_index2.action: "after" }
|
- match: { indices.my_index2.action: "after" }
|
||||||
- match: { my_index2.step: "after" }
|
- match: { indices.my_index2.step: "after" }
|
||||||
- is_false: my_index2.failed_step
|
- is_false: indices.my_index2.failed_step
|
||||||
- is_false: my_index2.step_info
|
- is_false: indices.my_index2.step_info
|
||||||
|
|
||||||
- is_true: another_index.managed
|
- is_true: indices.another_index.managed
|
||||||
- match: { another_index.index: "another_index" }
|
- match: { indices.another_index.index: "another_index" }
|
||||||
- match: { another_index.policy: "my_moveable_timeseries_lifecycle" }
|
- match: { indices.another_index.policy: "my_moveable_timeseries_lifecycle" }
|
||||||
- match: { another_index.phase: "new" }
|
- match: { indices.another_index.phase: "new" }
|
||||||
- match: { another_index.action: "after" }
|
- match: { indices.another_index.action: "after" }
|
||||||
- match: { another_index.step: "after" }
|
- match: { indices.another_index.step: "after" }
|
||||||
- is_false: another_index.failed_step
|
- is_false: indices.another_index.failed_step
|
||||||
- is_false: another_index.step_info
|
- is_false: indices.another_index.step_info
|
||||||
|
|
||||||
- match: { unmanaged_index.index: "unmanaged_index" }
|
- match: { indices.unmanaged_index.index: "unmanaged_index" }
|
||||||
- is_false: unmanaged_index.managed
|
- is_false: indices.unmanaged_index.managed
|
||||||
- is_false: unmanaged_index.policy
|
- is_false: indices.unmanaged_index.policy
|
||||||
- is_false: unmanaged_index.phase
|
- is_false: indices.unmanaged_index.phase
|
||||||
- is_false: unmanaged_index.action
|
- is_false: indices.unmanaged_index.action
|
||||||
- is_false: unmanaged_index.step
|
- is_false: indices.unmanaged_index.step
|
||||||
- is_false: another_index.failed_step
|
- is_false: indices.another_index.failed_step
|
||||||
- is_false: another_index.step_info
|
- is_false: indices.another_index.step_info
|
||||||
|
|
||||||
---
|
---
|
||||||
"Test Unmanaged Index Lifecycle Explain":
|
"Test Unmanaged Index Lifecycle Explain":
|
||||||
|
@ -202,14 +202,14 @@ teardown:
|
||||||
ilm.explain_lifecycle:
|
ilm.explain_lifecycle:
|
||||||
index: "unmanaged_index"
|
index: "unmanaged_index"
|
||||||
|
|
||||||
- match: { unmanaged_index.index: "unmanaged_index" }
|
- match: { indices.unmanaged_index.index: "unmanaged_index" }
|
||||||
- is_false: unmanaged_index.managed
|
- is_false: indices.unmanaged_index.managed
|
||||||
- is_false: unmanaged_index.policy
|
- is_false: indices.unmanaged_index.policy
|
||||||
- is_false: unmanaged_index.phase
|
- is_false: indices.unmanaged_index.phase
|
||||||
- is_false: unmanaged_index.action
|
- is_false: indices.unmanaged_index.action
|
||||||
- is_false: unmanaged_index.step
|
- is_false: indices.unmanaged_index.step
|
||||||
- is_false: another_index.failed_step
|
- is_false: indices.another_index.failed_step
|
||||||
- is_false: another_index.step_info
|
- is_false: indices.another_index.step_info
|
||||||
- is_false: my_index
|
- is_false: indices.my_index
|
||||||
- is_false: my_index2
|
- is_false: indices.my_index2
|
||||||
- is_false: another_index
|
- is_false: indices.another_index
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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.protocol.xpack.indexlifecycle;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.ActionRequestValidationException;
|
||||||
|
import org.elasticsearch.action.support.master.info.ClusterInfoRequest;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The request object used by the Explain Lifecycle API.
|
||||||
|
*
|
||||||
|
* Multiple indices may be queried in the same request using the
|
||||||
|
* {@link #indices(String...)} method
|
||||||
|
*/
|
||||||
|
public class ExplainLifecycleRequest extends ClusterInfoRequest<ExplainLifecycleRequest> {
|
||||||
|
|
||||||
|
public ExplainLifecycleRequest() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExplainLifecycleRequest(StreamInput in) throws IOException {
|
||||||
|
super(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionRequestValidationException validate() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(Arrays.hashCode(indices()), indicesOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj.getClass() != getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ExplainLifecycleRequest other = (ExplainLifecycleRequest) obj;
|
||||||
|
return Objects.deepEquals(indices(), other.indices()) &&
|
||||||
|
Objects.equals(indicesOptions(), other.indicesOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ExplainLifecycleRequest [indices()=" + Arrays.toString(indices()) + ", indicesOptions()=" + indicesOptions() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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.protocol.xpack.indexlifecycle;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.ActionResponse;
|
||||||
|
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.xcontent.ConstructingObjectParser;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The response object returned by the Explain Lifecycle API.
|
||||||
|
*
|
||||||
|
* Since the API can be run over multiple indices the response provides a map of
|
||||||
|
* index to the explanation of the lifecycle status for that index.
|
||||||
|
*/
|
||||||
|
public class ExplainLifecycleResponse extends ActionResponse implements ToXContentObject {
|
||||||
|
|
||||||
|
public static final ParseField INDICES_FIELD = new ParseField("indices");
|
||||||
|
|
||||||
|
private Map<String, IndexLifecycleExplainResponse> indexResponses;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static final ConstructingObjectParser<ExplainLifecycleResponse, Void> PARSER = new ConstructingObjectParser<>(
|
||||||
|
"explain_lifecycle_response", a -> new ExplainLifecycleResponse(((List<IndexLifecycleExplainResponse>) a[0]).stream()
|
||||||
|
.collect(Collectors.toMap(IndexLifecycleExplainResponse::getIndex, Function.identity()))));
|
||||||
|
static {
|
||||||
|
PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> IndexLifecycleExplainResponse.PARSER.apply(p, c),
|
||||||
|
INDICES_FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExplainLifecycleResponse fromXContent(XContentParser parser) {
|
||||||
|
return PARSER.apply(parser, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExplainLifecycleResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExplainLifecycleResponse(Map<String, IndexLifecycleExplainResponse> indexResponses) {
|
||||||
|
this.indexResponses = indexResponses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a map of the responses from each requested index. The maps key is
|
||||||
|
* the index name and the value is the
|
||||||
|
* {@link IndexLifecycleExplainResponse} describing the current
|
||||||
|
* lifecycle status of that index
|
||||||
|
*/
|
||||||
|
public Map<String, IndexLifecycleExplainResponse> getIndexResponses() {
|
||||||
|
return indexResponses;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.startObject();
|
||||||
|
builder.startObject(INDICES_FIELD.getPreferredName());
|
||||||
|
for (IndexLifecycleExplainResponse indexResponse : indexResponses.values()) {
|
||||||
|
builder.field(indexResponse.getIndex(), indexResponse);
|
||||||
|
}
|
||||||
|
builder.endObject();
|
||||||
|
builder.endObject();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
|
int size = in.readVInt();
|
||||||
|
Map<String, IndexLifecycleExplainResponse> indexResponses = new HashMap<>(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
IndexLifecycleExplainResponse indexResponse = new IndexLifecycleExplainResponse(in);
|
||||||
|
indexResponses.put(indexResponse.getIndex(), indexResponse);
|
||||||
|
}
|
||||||
|
this.indexResponses = indexResponses;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
out.writeVInt(indexResponses.size());
|
||||||
|
for (IndexLifecycleExplainResponse e : indexResponses.values()) {
|
||||||
|
e.writeTo(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(indexResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj.getClass() != getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ExplainLifecycleResponse other = (ExplainLifecycleResponse) obj;
|
||||||
|
return Objects.equals(indexResponses, other.indexResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Strings.toString(this, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,23 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* license agreements. See the NOTICE file distributed with
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* 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.xpack.core.indexlifecycle.action;
|
package org.elasticsearch.protocol.xpack.indexlifecycle;
|
||||||
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
|
@ -1,24 +1,36 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* license agreements. See the NOTICE file distributed with
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* 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.xpack.core.indexlifecycle.action;
|
package org.elasticsearch.protocol.xpack.indexlifecycle;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.IndicesOptions;
|
import org.elasticsearch.action.support.IndicesOptions;
|
||||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction.Request;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class ExplainLifecycleRequestTests extends AbstractWireSerializingTestCase<Request> {
|
public class ExplainLifecycleRequestTests extends AbstractWireSerializingTestCase<ExplainLifecycleRequest> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Request createTestInstance() {
|
protected ExplainLifecycleRequest createTestInstance() {
|
||||||
Request request = new Request();
|
ExplainLifecycleRequest request = new ExplainLifecycleRequest();
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
request.indices(generateRandomStringArray(20, 20, false, true));
|
request.indices(generateRandomStringArray(20, 20, false, true));
|
||||||
}
|
}
|
||||||
|
@ -31,7 +43,7 @@ public class ExplainLifecycleRequestTests extends AbstractWireSerializingTestCas
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Request mutateInstance(Request instance) throws IOException {
|
protected ExplainLifecycleRequest mutateInstance(ExplainLifecycleRequest instance) throws IOException {
|
||||||
String[] indices = instance.indices();
|
String[] indices = instance.indices();
|
||||||
IndicesOptions indicesOptions = instance.indicesOptions();
|
IndicesOptions indicesOptions = instance.indicesOptions();
|
||||||
switch (between(0, 1)) {
|
switch (between(0, 1)) {
|
||||||
|
@ -46,15 +58,15 @@ public class ExplainLifecycleRequestTests extends AbstractWireSerializingTestCas
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("Illegal randomisation branch");
|
throw new AssertionError("Illegal randomisation branch");
|
||||||
}
|
}
|
||||||
Request newRequest = new Request();
|
ExplainLifecycleRequest newRequest = new ExplainLifecycleRequest();
|
||||||
newRequest.indices(indices);
|
newRequest.indices(indices);
|
||||||
newRequest.indicesOptions(indicesOptions);
|
newRequest.indicesOptions(indicesOptions);
|
||||||
return newRequest;
|
return newRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Reader<Request> instanceReader() {
|
protected Reader<ExplainLifecycleRequest> instanceReader() {
|
||||||
return Request::new;
|
return ExplainLifecycleRequest::new;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.protocol.xpack.indexlifecycle;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ExplainLifecycleResponseTests extends AbstractStreamableXContentTestCase<ExplainLifecycleResponse> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExplainLifecycleResponse createTestInstance() {
|
||||||
|
Map<String, IndexLifecycleExplainResponse> indexResponses = new HashMap<>();
|
||||||
|
for (int i = 0; i < randomIntBetween(0, 2); i++) {
|
||||||
|
IndexLifecycleExplainResponse indexResponse = IndexExplainResponseTests.randomIndexExplainResponse();
|
||||||
|
indexResponses.put(indexResponse.getIndex(), indexResponse);
|
||||||
|
}
|
||||||
|
return new ExplainLifecycleResponse(indexResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExplainLifecycleResponse createBlankInstance() {
|
||||||
|
return new ExplainLifecycleResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExplainLifecycleResponse mutateInstance(ExplainLifecycleResponse response) {
|
||||||
|
Map<String, IndexLifecycleExplainResponse> indexResponses = new HashMap<>(response.getIndexResponses());
|
||||||
|
IndexLifecycleExplainResponse indexResponse = IndexExplainResponseTests.randomIndexExplainResponse();
|
||||||
|
indexResponses.put(indexResponse.getIndex(), indexResponse);
|
||||||
|
return new ExplainLifecycleResponse(indexResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExplainLifecycleResponse doParseInstance(XContentParser parser) throws IOException {
|
||||||
|
return ExplainLifecycleResponse.fromXContent(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean supportsUnknownFields() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,36 @@
|
||||||
/*
|
/*
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* license agreements. See the NOTICE file distributed with
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* 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.xpack.core.indexlifecycle.action;
|
package org.elasticsearch.protocol.xpack.indexlifecycle;
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||||
import org.elasticsearch.xpack.core.indexlifecycle.RandomStepInfo;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class IndexExplainResponseTests extends AbstractSerializingTestCase<IndexLifecycleExplainResponse> {
|
public class IndexExplainResponseTests extends AbstractSerializingTestCase<IndexLifecycleExplainResponse> {
|
||||||
|
|
||||||
|
@ -137,4 +153,45 @@ public class IndexExplainResponseTests extends AbstractSerializingTestCase<Index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class RandomStepInfo implements ToXContentObject {
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
RandomStepInfo(Supplier<String> randomStringSupplier) {
|
||||||
|
this.key = randomStringSupplier.get();
|
||||||
|
this.value = randomStringSupplier.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.startObject();
|
||||||
|
builder.field(key, value);
|
||||||
|
builder.endObject();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RandomStepInfo other = (RandomStepInfo) obj;
|
||||||
|
return Objects.equals(key, other.key) && Objects.equals(value, other.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Strings.toString(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue