Skip to content

Commit

Permalink
Adds an API to remove ILM from an index completely (#31358)
Browse files Browse the repository at this point in the history
* Adds an API to remove ILM from an index completely

The removal will only happen if the index is not in the shrink action

* Fixes compile issues
  • Loading branch information
colings86 authored and jasontedor committed Aug 17, 2018
1 parent 7ff6b71 commit 7d211ad
Show file tree
Hide file tree
Showing 11 changed files with 849 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.elasticsearch.xpack.core.indexlifecycle.action.GetLifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.MoveToStepAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.PutLifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.RemovePolicyForIndexAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.RetryAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction;
import org.elasticsearch.xpack.core.logstash.LogstashFeatureSetUsage;
Expand Down Expand Up @@ -337,6 +338,7 @@ public List<GenericAction> getClientActions() {
PutLifecycleAction.INSTANCE,
ExplainLifecycleAction.INSTANCE,
SetPolicyForIndexAction.INSTANCE,
RemovePolicyForIndexAction.INSTANCE,
MoveToStepAction.INSTANCE,
RetryAction.INSTANCE
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
* 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.action.Action;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
import org.elasticsearch.common.ParseField;
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 java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class RemovePolicyForIndexAction extends Action<RemovePolicyForIndexAction.Response> {
public static final RemovePolicyForIndexAction INSTANCE = new RemovePolicyForIndexAction();
public static final String NAME = "indices:admin/xpack/index_lifecycle/remove_policy";

protected RemovePolicyForIndexAction() {
super(NAME);
}

@Override
public RemovePolicyForIndexAction.Response newResponse() {
return new Response();
}

public static class Response extends ActionResponse implements ToXContentObject {

public static final ParseField HAS_FAILURES_FIELD = new ParseField("has_failures");
public static final ParseField FAILED_INDEXES_FIELD = new ParseField("failed_indexes");
@SuppressWarnings("unchecked")
public static final ConstructingObjectParser<Response, Void> PARSER = new ConstructingObjectParser<>(
"change_policy_for_index_response", a -> new Response((List<String>) a[0]));
static {
PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), FAILED_INDEXES_FIELD);
// Needs to be declared but not used in constructing the response object
PARSER.declareBoolean(ConstructingObjectParser.constructorArg(), HAS_FAILURES_FIELD);
}

private List<String> failedIndexes;

public Response() {
}

public Response(List<String> failedIndexes) {
if (failedIndexes == null) {
throw new IllegalArgumentException(FAILED_INDEXES_FIELD.getPreferredName() + " cannot be null");
}
this.failedIndexes = failedIndexes;
}

public List<String> getFailedIndexes() {
return failedIndexes;
}

public boolean hasFailures() {
return failedIndexes.isEmpty() == false;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field(HAS_FAILURES_FIELD.getPreferredName(), hasFailures());
builder.field(FAILED_INDEXES_FIELD.getPreferredName(), failedIndexes);
builder.endObject();
return builder;
}

@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
failedIndexes = in.readList(StreamInput::readString);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeStringList(failedIndexes);
}

@Override
public int hashCode() {
return Objects.hash(failedIndexes);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Response other = (Response) obj;
return Objects.equals(failedIndexes, other.failedIndexes);
}

}

public static class Request extends AcknowledgedRequest<Request> implements IndicesRequest.Replaceable {

private String[] indices;
private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen();

public Request() {
}

public Request(String... indices) {
if (indices == null) {
throw new IllegalArgumentException("indices cannot be null");
}
this.indices = indices;
}

@Override
public Request indices(String... indices) {
this.indices = indices;
return this;
}

@Override
public String[] indices() {
return indices;
}

public void indicesOptions(IndicesOptions indicesOptions) {
this.indicesOptions = indicesOptions;
}

public IndicesOptions indicesOptions() {
return indicesOptions;
}

@Override
public ActionRequestValidationException validate() {
return null;
}

@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
indices = in.readStringArray();
indicesOptions = IndicesOptions.readIndicesOptions(in);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeStringArray(indices);
indicesOptions.writeIndicesOptions(out);
}

@Override
public int hashCode() {
return Objects.hash(Arrays.hashCode(indices), indicesOptions);
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Request other = (Request) obj;
return Objects.deepEquals(indices, other.indices) &&
Objects.equals(indicesOptions, other.indicesOptions);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.action.support.IndicesOptions;
import org.elasticsearch.test.AbstractStreamableTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.action.RemovePolicyForIndexAction.Request;

import java.io.IOException;
import java.util.Arrays;

public class RemovePolicyForIndexRequestTests extends AbstractStreamableTestCase<RemovePolicyForIndexAction.Request> {

@Override
protected Request createTestInstance() {
Request request = new Request(generateRandomStringArray(20, 20, false));
if (randomBoolean()) {
IndicesOptions indicesOptions = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(),
randomBoolean(), randomBoolean(), randomBoolean());
request.indicesOptions(indicesOptions);
}
if (randomBoolean()) {
request.indices(generateRandomStringArray(20, 20, false));
}
return request;
}

@Override
protected Request createBlankInstance() {
return new Request();
}

@Override
protected Request mutateInstance(Request instance) throws IOException {
String[] indices = instance.indices();
IndicesOptions indicesOptions = instance.indicesOptions();
switch (between(0, 1)) {
case 0:
indices = randomValueOtherThanMany(i -> Arrays.equals(i, instance.indices()),
() -> generateRandomStringArray(20, 20, false));
break;
case 1:
indicesOptions = randomValueOtherThan(indicesOptions, () -> IndicesOptions.fromOptions(randomBoolean(), randomBoolean(),
randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()));
break;
default:
throw new AssertionError("Illegal randomisation branch");
}
Request newRequest = new Request(indices);
newRequest.indicesOptions(indicesOptions);
return newRequest;
}

public void testNullIndices() {
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
() -> new Request((String[]) null));
assertEquals("indices cannot be null", exception.getMessage());
}

public void testValidate() {
Request request = createTestInstance();
assertNull(request.validate());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.xcontent.XContentParser;
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.action.RemovePolicyForIndexAction.Response;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class RemovePolicyForIndexResponseTests extends AbstractStreamableXContentTestCase<RemovePolicyForIndexAction.Response> {

@Override
protected Response createBlankInstance() {
return new Response();
}

@Override
protected Response createTestInstance() {
List<String> failedIndexes = Arrays.asList(generateRandomStringArray(20, 20, false));
return new Response(failedIndexes);
}

@Override
protected Response mutateInstance(Response instance) throws IOException {
List<String> failedIndices = randomValueOtherThan(instance.getFailedIndexes(),
() -> Arrays.asList(generateRandomStringArray(20, 20, false)));
return new Response(failedIndices);
}

@Override
protected Response doParseInstance(XContentParser parser) throws IOException {
return Response.PARSER.apply(parser, null);
}

@Override
protected boolean supportsUnknownFields() {
return false;
}

public void testNullFailedIndices() {
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> new Response((List<String>) null));
assertEquals("failed_indexes cannot be null", exception.getMessage());
}

public void testHasFailures() {
Response response = new Response(new ArrayList<>());
assertFalse(response.hasFailures());
assertEquals(Collections.emptyList(), response.getFailedIndexes());

int size = randomIntBetween(1, 10);
List<String> failedIndexes = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
failedIndexes.add(randomAlphaOfLength(20));
}
response = new Response(failedIndexes);
assertTrue(response.hasFailures());
assertEquals(failedIndexes, response.getFailedIndexes());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,30 @@
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.DeleteLifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.GetLifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.MoveToStepAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.PutLifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.RemovePolicyForIndexAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.RetryAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestSetPolicyForIndexAction;
import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestDeleteLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestExplainLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestGetLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestMoveToStepAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestPutLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestRemovePolicyForIndexAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestRetryAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportSetPolicyForIndexAction;
import org.elasticsearch.xpack.indexlifecycle.action.RestSetPolicyForIndexAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportDeleteLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportExplainLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportGetLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportMoveToStepAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportPutLifecycleAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportRemovePolicyForIndexAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportRetryAction;
import org.elasticsearch.xpack.indexlifecycle.action.TransportSetPolicyForIndexAction;

import java.time.Clock;
import java.util.ArrayList;
Expand Down Expand Up @@ -151,6 +154,7 @@ public List<RestHandler> getRestHandlers(Settings settings, RestController restC
new RestDeleteLifecycleAction(settings, restController),
new RestExplainLifecycleAction(settings, restController),
new RestSetPolicyForIndexAction(settings, restController),
new RestRemovePolicyForIndexAction(settings, restController),
new RestMoveToStepAction(settings, restController),
new RestRetryAction(settings, restController)
);
Expand All @@ -167,6 +171,7 @@ public List<RestHandler> getRestHandlers(Settings settings, RestController restC
new ActionHandler<>(DeleteLifecycleAction.INSTANCE, TransportDeleteLifecycleAction.class),
new ActionHandler<>(ExplainLifecycleAction.INSTANCE, TransportExplainLifecycleAction.class),
new ActionHandler<>(SetPolicyForIndexAction.INSTANCE, TransportSetPolicyForIndexAction.class),
new ActionHandler<>(RemovePolicyForIndexAction.INSTANCE, TransportRemovePolicyForIndexAction.class),
new ActionHandler<>(MoveToStepAction.INSTANCE, TransportMoveToStepAction.class),
new ActionHandler<>(RetryAction.INSTANCE, TransportRetryAction.class));
}
Expand Down
Loading

0 comments on commit 7d211ad

Please sign in to comment.