Skip to content

Commit

Permalink
Make the ILM freeze action a no-op
Browse files Browse the repository at this point in the history
This changes the ILM `freeze` action to not actually freeze the index, instead performing no
operation.

Relates to elastic#70192
  • Loading branch information
dakrone committed Sep 1, 2021
1 parent edcdd30 commit 144b3ce
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 149 deletions.
5 changes: 1 addition & 4 deletions docs/reference/ilm/actions/ilm-freeze.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ Phases allowed: cold.

<<freeze-index-api, Freezes>> an index.

IMPORTANT: Freezing an index closes the index and reopens it within the same API call.
This means that for a short time no primaries are allocated.
The cluster will go red until the primaries are allocated.
This limitation might be removed in the future.
deprecated[7.x,"The ILM Freeze action was deprecated in 7.x and will be treated as a no-op in 8.0+."]

[[ilm-freeze-options]]
==== Options
Expand Down
12 changes: 12 additions & 0 deletions docs/reference/migration/migrate_8_0/ilm.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,16 @@ renamed to `ilm` to match the package rename inside the {es} code.
Update your workflow and applications to use the `ilm` package in place of
`indexlifecycle`.
====

[[ilm-freeze-zoop]]
.The ILM `freeze` action is now a no-op.
[%collapsible]
====
*Details* +
The ILM freeze action is now a no-op and performs no action on the index, as the freeze API endpoint
has been removed in 8.0.
*Impact* +
Update your ILM policies to remove the `freeze` action from the `cold` phase.
====
// end::notable-breaking-changes[]
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@
*/
package org.elasticsearch.xpack.core.ilm;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.protocol.xpack.frozen.FreezeRequest;
import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction;

/**
* Freezes an index.
*/
@Deprecated // To be removed in 9.0
public class FreezeStep extends AsyncRetryDuringSnapshotActionStep {
public static final String NAME = "freeze";

Expand All @@ -27,14 +24,8 @@ public FreezeStep(StepKey key, StepKey nextStepKey, Client client) {

@Override
public void performDuringNoSnapshot(IndexMetadata indexMetadata, ClusterState currentState, ActionListener<Void> listener) {
getClient().admin().indices().execute(FreezeIndexAction.INSTANCE,
new FreezeRequest(indexMetadata.getIndex().getName()).masterNodeTimeout(TimeValue.MAX_VALUE),
ActionListener.wrap(response -> {
if (response.isAcknowledged() == false) {
throw new ElasticsearchException("freeze index request failed to be acknowledged");
}
listener.onResponse(null);
}, listener::onFailure));
// Deprecated in 7.x, the freeze action is a noop in 8.x, so immediately return here
listener.onResponse(null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,8 @@


import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.protocol.xpack.frozen.FreezeRequest;
import org.elasticsearch.protocol.xpack.frozen.FreezeResponse;
import org.elasticsearch.xpack.core.frozen.action.FreezeIndexAction;
import org.elasticsearch.xpack.core.ilm.Step.StepKey;
import org.mockito.Mockito;

import static org.hamcrest.Matchers.is;

public class FreezeStepTests extends AbstractStepTestCase<FreezeStep> {

Expand Down Expand Up @@ -62,59 +53,4 @@ private static IndexMetadata getIndexMetadata() {
public void testIndexSurvives() {
assertTrue(createRandomInstance().indexSurvives());
}

public void testFreeze() throws Exception {
IndexMetadata indexMetadata = getIndexMetadata();

Mockito.doAnswer(invocation -> {
assertSame(invocation.getArguments()[0], FreezeIndexAction.INSTANCE);
FreezeRequest request = (FreezeRequest) invocation.getArguments()[1];
@SuppressWarnings("unchecked")
ActionListener<AcknowledgedResponse> listener = (ActionListener<AcknowledgedResponse>) invocation.getArguments()[2];
assertNotNull(request);
assertEquals(1, request.indices().length);
assertEquals(indexMetadata.getIndex().getName(), request.indices()[0]);
listener.onResponse(new FreezeResponse(true, true));
return null;
}).when(indicesClient).execute(Mockito.any(), Mockito.any(), Mockito.any());

FreezeStep step = createRandomInstance();
PlainActionFuture.<Void, Exception>get(f -> step.performAction(indexMetadata, emptyClusterState(), null, f));

Mockito.verify(client, Mockito.only()).admin();
Mockito.verify(adminClient, Mockito.only()).indices();
Mockito.verify(indicesClient, Mockito.only()).execute(Mockito.any(), Mockito.any(), Mockito.any());
}

public void testExceptionThrown() {
IndexMetadata indexMetadata = getIndexMetadata();
Exception exception = new RuntimeException();

Mockito.doAnswer(invocation -> {
@SuppressWarnings("unchecked")
ActionListener<AcknowledgedResponse> listener = (ActionListener<AcknowledgedResponse>) invocation.getArguments()[2];
listener.onFailure(exception);
return null;
}).when(indicesClient).execute(Mockito.any(), Mockito.any(), Mockito.any());

FreezeStep step = createRandomInstance();
assertSame(exception, expectThrows(Exception.class, () -> PlainActionFuture.<Void, Exception>get(
f -> step.performAction(indexMetadata, emptyClusterState(), null, f))));
}

public void testNotAcknowledged() {
IndexMetadata indexMetadata = getIndexMetadata();

Mockito.doAnswer(invocation -> {
@SuppressWarnings("unchecked")
ActionListener<AcknowledgedResponse> listener = (ActionListener<AcknowledgedResponse>) invocation.getArguments()[2];
listener.onResponse(new FreezeResponse(false, false));
return null;
}).when(indicesClient).execute(Mockito.any(), Mockito.any(), Mockito.any());

FreezeStep step = createRandomInstance();
Exception e = expectThrows(Exception.class,
() -> PlainActionFuture.<Void, Exception>get(f -> step.performAction(indexMetadata, emptyClusterState(), null, f)));
assertThat(e.getMessage(), is("freeze index request failed to be acknowledged"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.xpack.core.ilm.CheckNotDataStreamWriteIndexStep;
import org.elasticsearch.xpack.core.ilm.DeleteAction;
Expand Down Expand Up @@ -187,9 +186,7 @@ public void testFreezeAction() throws Exception {
TimeUnit.SECONDS);

Map<String, Object> settings = getOnlyIndexSettings(client(), backingIndexName);
assertThat(settings.get(IndexMetadata.SETTING_BLOCKS_WRITE), equalTo("true"));
assertThat(settings.get(IndexSettings.INDEX_SEARCH_THROTTLED.getKey()), equalTo("true"));
assertThat(settings.get("index.frozen"), equalTo("true"));
assertNull(settings.get("index.frozen"));
}

public void testForceMergeAction() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.elasticsearch.core.CheckedRunnable;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.engine.EngineConfig;
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateAction;
import org.elasticsearch.snapshots.SnapshotState;
Expand Down Expand Up @@ -143,24 +142,17 @@ public void testRetryFailedDeleteAction() throws Exception {
assertBusy(() -> assertFalse(indexExists(index)));
}

public void testRetryFreezeDeleteAction() throws Exception {
public void testFreezeNoop() throws Exception {
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction());

createIndexWithSettings(client(), index, alias, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(IndexMetadata.SETTING_READ_ONLY, true)
.put("index.lifecycle.name", policy));

assertBusy(() -> assertThat((Integer) explainIndex(client(), index).get(FAILED_STEP_RETRY_COUNT_FIELD), greaterThanOrEqualTo(1)),
assertBusy(() -> assertThat(getStepKeyForIndex(client(), index), equalTo(PhaseCompleteStep.finalStep("cold").getKey())),
30, TimeUnit.SECONDS);
assertFalse(getOnlyIndexSettings(client(), index).containsKey("index.frozen"));

Request request = new Request("PUT", index + "/_settings");
request.setJsonEntity("{\"index.blocks.read_only\":false}");
assertOK(client().performRequest(request));

assertBusy(() -> assertThat(getOnlyIndexSettings(client(), index).get("index.frozen"), equalTo("true")));
}


Expand Down Expand Up @@ -416,61 +408,6 @@ public void testForceMergeActionWithCompressionCodec() throws Exception {
forceMergeActionWithCodec("best_compression");
}

public void testFreezeAction() throws Exception {
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction());
updatePolicy(client(), index, policy);
assertBusy(() -> {
Map<String, Object> settings = getOnlyIndexSettings(client(), index);
assertThat(getStepKeyForIndex(client(), index), equalTo(PhaseCompleteStep.finalStep("cold").getKey()));
assertThat(settings.get(IndexMetadata.INDEX_BLOCKS_WRITE_SETTING.getKey()), equalTo("true"));
assertThat(settings.get(IndexSettings.INDEX_SEARCH_THROTTLED.getKey()), equalTo("true"));
assertThat(settings.get("index.frozen"), equalTo("true"));
});
}

public void testFreezeDuringSnapshot() throws Exception {
// Create the repository before taking the snapshot.
Request request = new Request("PUT", "/_snapshot/repo");
request.setJsonEntity(Strings
.toString(JsonXContent.contentBuilder()
.startObject()
.field("type", "fs")
.startObject("settings")
.field("compress", randomBoolean())
.field("location", System.getProperty("tests.path.repo"))
.field("max_snapshot_bytes_per_sec", "256b")
.endObject()
.endObject()));
assertOK(client().performRequest(request));
// create delete policy
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction(), TimeValue.timeValueMillis(0));
// create index without policy
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
// index document so snapshot actually does something
indexDocument(client(), index);
// start snapshot
request = new Request("PUT", "/_snapshot/repo/snapshot");
request.addParameter("wait_for_completion", "false");
request.setJsonEntity("{\"indices\": \"" + index + "\"}");
assertOK(client().performRequest(request));
// add policy and expect it to trigger delete immediately (while snapshot in progress)
updatePolicy(client(), index, policy);
// assert that the index froze
assertBusy(() -> {
Map<String, Object> settings = getOnlyIndexSettings(client(), index);
assertThat(getStepKeyForIndex(client(), index), equalTo(PhaseCompleteStep.finalStep("cold").getKey()));
assertThat(settings.get(IndexMetadata.INDEX_BLOCKS_WRITE_SETTING.getKey()), equalTo("true"));
assertThat(settings.get(IndexSettings.INDEX_SEARCH_THROTTLED.getKey()), equalTo("true"));
assertThat(settings.get("index.frozen"), equalTo("true"));
}, 2, TimeUnit.MINUTES);
// assert that snapshot is still in progress and clean up
assertThat(getSnapshotState(client(), "snapshot"), equalTo("SUCCESS"));
assertOK(client().performRequest(new Request("DELETE", "/_snapshot/repo/snapshot")));
}

public void testSetPriority() throws Exception {
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0).put(IndexMetadata.INDEX_PRIORITY_SETTING.getKey(), 100));
Expand Down

0 comments on commit 144b3ce

Please sign in to comment.