Skip to content

Commit

Permalink
Adding deprecation logging and deprecation info API for ILM freeze at…
Browse files Browse the repository at this point in the history
…ion (#77969)

As part of deprecating frozen indices in favor of the frozen tier, this commit deprecates the ILM freeze action. This
includes a deprecation log message at runtime, as well as a deprecation info API check.
Relates #70192 #42404
  • Loading branch information
masseyke authored Sep 21, 2021
1 parent 4f79234 commit dfc9a8e
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
private static final Set<String> VALID_WARM_ACTIONS = Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, AllocateAction.NAME,
ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME);
private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, AllocateAction.NAME,
FreezeAction.NAME, SearchableSnapshotAction.NAME);
SearchableSnapshotAction.NAME);
private static final Set<String> VALID_DELETE_ACTIONS = Sets.newHashSet(DeleteAction.NAME, WaitForSnapshotAction.NAME);

private String lifecycleName;
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/ilm/actions/ilm-freeze.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ PUT _ilm/policy/my_policy
}
}
--------------------------------------------------

// TEST[warning:the freeze action has been deprecated and will be removed in a future release]
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
*/
package org.elasticsearch.xpack.core.ilm;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.rollup.RollupV2;
Expand Down Expand Up @@ -41,7 +45,8 @@
*/
public class TimeseriesLifecycleType implements LifecycleType {
public static final TimeseriesLifecycleType INSTANCE = new TimeseriesLifecycleType();

private static final Logger logger = LogManager.getLogger(TimeseriesLifecycleType.class);
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(logger.getName());
public static final String TYPE = "timeseries";

static final String HOT_PHASE = "hot";
Expand All @@ -51,6 +56,9 @@ public class TimeseriesLifecycleType implements LifecycleType {
static final String DELETE_PHASE = "delete";
static final List<String> ORDERED_VALID_PHASES = Arrays.asList(HOT_PHASE, WARM_PHASE, COLD_PHASE, FROZEN_PHASE, DELETE_PHASE);

public static final String FREEZE_ACTION_DEPRECATION_WARNING = "the freeze action has been deprecated and will be removed in a future" +
" release";

static final List<String> ORDERED_VALID_HOT_ACTIONS = Stream.of(SetPriorityAction.NAME, UnfollowAction.NAME, RolloverAction.NAME,
ReadOnlyAction.NAME, RollupV2.isEnabled() ? RollupILMAction.NAME : null, ShrinkAction.NAME, ForceMergeAction.NAME,
SearchableSnapshotAction.NAME)
Expand Down Expand Up @@ -296,6 +304,13 @@ public void validate(Collection<Phase> phases) {
validateActionsFollowingSearchableSnapshot(phases);
validateAllSearchableSnapshotActionsUseSameRepository(phases);
validateFrozenPhaseHasSearchableSnapshotAction(phases);
logDeprecationWarningForFreezeAction(phases);
}

private void logDeprecationWarningForFreezeAction(Collection<Phase> phases) {
if (phases.stream().anyMatch(phase -> phase.getActions().containsKey(FreezeAction.NAME))) {
deprecationLogger.deprecate(DeprecationCategory.OTHER, "ilm_freee_action", FREEZE_ACTION_DEPRECATION_WARNING);
}
}

static void validateActionsFollowingSearchableSnapshot(Collection<Phase> phases) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,17 @@ public void testValidateColdPhase() {
}
}

public void testFreezeActionDeprecationLog() {
Map<String, LifecycleAction> actions = randomSubsetOf(VALID_COLD_ACTIONS)
.stream().map(this::getTestAction).collect(Collectors.toMap(LifecycleAction::getWriteableName, Function.identity()));
if (actions.containsKey(FreezeAction.NAME) == false) {
actions.put(FreezeAction.NAME, getTestAction(FreezeAction.NAME));
}
Map<String, Phase> coldPhase = Collections.singletonMap("cold", new Phase("cold", TimeValue.ZERO, actions));
TimeseriesLifecycleType.INSTANCE.validate(coldPhase.values());
assertSettingDeprecationsAndWarnings(new String[0], TimeseriesLifecycleType.FREEZE_ACTION_DEPRECATION_WARNING);
}

public void testValidateDeletePhase() {
LifecycleAction invalidAction = null;
Map<String, LifecycleAction> actions = VALID_DELETE_ACTIONS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@
import org.elasticsearch.ingest.IngestService;
import org.elasticsearch.ingest.PipelineConfiguration;
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
import org.elasticsearch.xpack.core.ilm.FreezeAction;
import org.elasticsearch.xpack.core.ilm.IndexLifecycleMetadata;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
Expand Down Expand Up @@ -380,4 +383,32 @@ static DeprecationIssue checkSparseVectorTemplates(final ClusterState clusterSta
return null;
}
}

static DeprecationIssue checkILMFreezeActions(ClusterState state) {
IndexLifecycleMetadata indexLifecycleMetadata = state.getMetadata().custom("index_lifecycle");
if (indexLifecycleMetadata != null) {
List<String> policiesWithFreezeActions =
indexLifecycleMetadata.getPolicies().entrySet().stream()
.filter(nameAndPolicy ->
nameAndPolicy.getValue().getPhases().values().stream()
.anyMatch(phase -> phase != null && phase.getActions() != null &&
phase.getActions().containsKey(FreezeAction.NAME)))
.map(nameAndPolicy -> nameAndPolicy.getKey())
.collect(Collectors.toList());
if (policiesWithFreezeActions.isEmpty() == false) {
String details = String.format(
Locale.ROOT,
"remove freeze action from the following ilm policies: [%s]",
policiesWithFreezeActions.stream().sorted().collect(Collectors.joining(","))
);
return new DeprecationIssue(DeprecationIssue.Level.WARNING,
"some ilm policies contain a freeze action, which is deprecated and will be removed in a future release",
"https://ela.st/es-deprecation-7-frozen-indices",
details,
false,
null);
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ private DeprecationChecks() {
ClusterDeprecationChecks::checkTemplatesWithMultipleTypes,
ClusterDeprecationChecks::checkClusterRoutingAllocationIncludeRelocationsSetting,
ClusterDeprecationChecks::checkGeoShapeTemplates,
ClusterDeprecationChecks::checkSparseVectorTemplates
ClusterDeprecationChecks::checkSparseVectorTemplates,
ClusterDeprecationChecks::checkILMFreezeActions
));

static final List<NodeDeprecationCheck<Settings, PluginsAndModules, ClusterState, XPackLicenseState, DeprecationIssue>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,25 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
import org.elasticsearch.ingest.IngestService;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
import org.elasticsearch.xpack.core.ilm.IndexLifecycleMetadata;
import org.elasticsearch.xpack.core.ilm.LifecycleAction;
import org.elasticsearch.xpack.core.ilm.LifecyclePolicy;
import org.elasticsearch.xpack.core.ilm.LifecyclePolicyMetadata;
import org.elasticsearch.xpack.core.ilm.OperationMode;
import org.elasticsearch.xpack.core.ilm.Phase;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static java.util.Collections.singletonList;
import static org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_INCLUDE_RELOCATIONS_SETTING;
Expand Down Expand Up @@ -514,4 +522,35 @@ public void testSparseVectorMappings() throws Exception {
"[my_sparse_vector], [my_nested_sparse_vector]", false, null)
));
}

public void testCheckILMFreezeActions() throws Exception {
Map<String, LifecyclePolicyMetadata> policies = new HashMap<>();
Map<String, Phase> phases1 = new HashMap<>();
Map<String, LifecycleAction> coldActions = new HashMap<>();
coldActions.put("freeze", null);
Phase coldPhase = new Phase("cold", TimeValue.ZERO, coldActions);
Phase somePhase = new Phase("somePhase", TimeValue.ZERO, null);
phases1.put("cold", coldPhase);
phases1.put("somePhase", somePhase);
LifecyclePolicy policy1 = new LifecyclePolicy("policy1", phases1, null);
LifecyclePolicyMetadata policy1Metadata = new LifecyclePolicyMetadata(policy1, null, 0, 0);
policies.put("policy1", policy1Metadata);
Map<String, Phase> phases2 = new HashMap<>();
phases2.put("cold", coldPhase);
LifecyclePolicy policy2 = new LifecyclePolicy("policy2", phases2, null);
LifecyclePolicyMetadata policy2Metadata = new LifecyclePolicyMetadata(policy2, null, 0, 0);
policies.put("policy2", policy2Metadata);
Metadata.Custom lifecycle = new IndexLifecycleMetadata(policies, OperationMode.RUNNING);
Metadata badMetadata = Metadata.builder()
.putCustom("index_lifecycle", lifecycle)
.build();
ClusterState badState = ClusterState.builder(new ClusterName("test")).metadata(badMetadata).build();
DeprecationIssue issue = ClusterDeprecationChecks.checkILMFreezeActions(badState);
assertThat(issue, equalTo(
new DeprecationIssue(DeprecationIssue.Level.WARNING,
"some ilm policies contain a freeze action, which is deprecated and will be removed in a future release",
"https://ela.st/es-deprecation-7-frozen-indices",
"remove freeze action from the following ilm policies: [policy1,policy2]", false, null)
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.xpack.core.ilm.AllocateAction;
import org.elasticsearch.xpack.core.ilm.DeleteAction;
import org.elasticsearch.xpack.core.ilm.ForceMergeAction;
Expand Down Expand Up @@ -126,11 +127,22 @@ public static void index(RestClient client, String index, String id, Object... f

public static void createNewSingletonPolicy(RestClient client, String policyName, String phaseName, LifecycleAction action)
throws IOException {
createNewSingletonPolicy(client, policyName, phaseName, action, TimeValue.ZERO);
createNewSingletonPolicy(client, policyName, phaseName, action, (RequestOptions) null);
}

public static void createNewSingletonPolicy(RestClient client, String policyName, String phaseName, LifecycleAction action,
RequestOptions requestOptions)
throws IOException {
createNewSingletonPolicy(client, policyName, phaseName, action, TimeValue.ZERO, requestOptions);
}

public static void createNewSingletonPolicy(RestClient client, String policyName, String phaseName, LifecycleAction action,
TimeValue after) throws IOException {
createNewSingletonPolicy(client, policyName, phaseName, action, after, null);
}

public static void createNewSingletonPolicy(RestClient client, String policyName, String phaseName, LifecycleAction action,
TimeValue after, RequestOptions requestOptions) throws IOException {
Phase phase = new Phase(phaseName, after, singletonMap(action.getWriteableName(), action));
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy(policyName, singletonMap(phase.getName(), phase));
XContentBuilder builder = jsonBuilder();
Expand All @@ -139,6 +151,9 @@ public static void createNewSingletonPolicy(RestClient client, String policyName
"{ \"policy\":" + Strings.toString(builder) + "}", ContentType.APPLICATION_JSON);
Request request = new Request("PUT", "_ilm/policy/" + policyName);
request.setEntity(entity);
if (requestOptions != null) {
request.setOptions(requestOptions);
}
client.performRequest(request);
}

Expand Down Expand Up @@ -204,6 +219,13 @@ public static void createFullPolicy(RestClient client, String policyName, TimeVa
public static void createPolicy(RestClient client, String policyName, @Nullable Phase hotPhase,
@Nullable Phase warmPhase, @Nullable Phase coldPhase,
@Nullable Phase frozenPhase, @Nullable Phase deletePhase) throws IOException {
createPolicy(client, policyName, hotPhase, warmPhase, coldPhase, frozenPhase, deletePhase, null);
}

public static void createPolicy(RestClient client, String policyName, @Nullable Phase hotPhase,
@Nullable Phase warmPhase, @Nullable Phase coldPhase,
@Nullable Phase frozenPhase, @Nullable Phase deletePhase, @Nullable RequestOptions requestOptions)
throws IOException {
if (hotPhase == null && warmPhase == null && coldPhase == null && deletePhase == null) {
throw new IllegalArgumentException("specify at least one phase");
}
Expand All @@ -230,6 +252,9 @@ public static void createPolicy(RestClient client, String policyName, @Nullable
"{ \"policy\":" + Strings.toString(builder) + "}", ContentType.APPLICATION_JSON);
Request request = new Request("PUT", "_ilm/policy/" + policyName);
request.setEntity(entity);
if (requestOptions != null) {
request.setOptions(requestOptions);
}
client.performRequest(request);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.elasticsearch.xpack.core.ilm.RolloverAction;
import org.elasticsearch.xpack.core.ilm.SearchableSnapshotAction;
import org.elasticsearch.xpack.core.ilm.ShrinkAction;
import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType;
import org.elasticsearch.xpack.core.ilm.WaitForRolloverReadyStep;
import org.junit.Before;

Expand Down Expand Up @@ -185,7 +186,8 @@ public void testReadOnlyAction() throws Exception {
}

public void testFreezeAction() throws Exception {
createNewSingletonPolicy(client(), policyName, "cold", new FreezeAction());
createNewSingletonPolicy(client(), policyName, "cold", new FreezeAction(),
expectWarnings(TimeseriesLifecycleType.FREEZE_ACTION_DEPRECATION_WARNING));
createComposableTemplate(client(), template, dataStream + "*", getTemplate(policyName));
indexDocument(client(), dataStream, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.elasticsearch.xpack.core.ilm.SearchableSnapshotAction;
import org.elasticsearch.xpack.core.ilm.SetPriorityAction;
import org.elasticsearch.xpack.core.ilm.Step;
import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType;
import org.elasticsearch.xpack.core.ilm.WaitForActiveShardsStep;
import org.elasticsearch.xpack.core.ilm.WaitForRolloverReadyStep;
import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction;
Expand Down Expand Up @@ -145,7 +146,8 @@ public void testRetryFailedDeleteAction() throws Exception {
}

public void testRetryFreezeDeleteAction() throws Exception {
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction());
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction(),
expectWarnings(TimeseriesLifecycleType.FREEZE_ACTION_DEPRECATION_WARNING));

createIndexWithSettings(client(), index, alias, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
Expand Down Expand Up @@ -423,7 +425,8 @@ public void testForceMergeActionWithCompressionCodec() throws Exception {
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());
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction(),
expectWarnings(TimeseriesLifecycleType.FREEZE_ACTION_DEPRECATION_WARNING));
updatePolicy(client(), index, policy);
assertBusy(() -> {
Map<String, Object> settings = getOnlyIndexSettings(client(), index);
Expand All @@ -449,7 +452,8 @@ public void testFreezeDuringSnapshot() throws Exception {
.endObject()));
assertOK(client().performRequest(request));
// create delete policy
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction(), TimeValue.timeValueMillis(0));
createNewSingletonPolicy(client(), policy, "cold", new FreezeAction(), TimeValue.timeValueMillis(0),
expectWarnings(TimeseriesLifecycleType.FREEZE_ACTION_DEPRECATION_WARNING));
// create index without policy
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.elasticsearch.xpack.core.ilm.SetPriorityAction;
import org.elasticsearch.xpack.core.ilm.ShrinkAction;
import org.elasticsearch.xpack.core.ilm.Step;
import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType;
import org.junit.Before;

import java.io.IOException;
Expand Down Expand Up @@ -337,7 +338,7 @@ public void testRestoredIndexManagedByLocalPolicySkipsIllegalActions() throws Ex
new ForceMergeAction(1, null))
),
new Phase("cold", TimeValue.ZERO, org.elasticsearch.core.Map.of(FreezeAction.NAME, new FreezeAction())),
null, null
null, null, expectWarnings(TimeseriesLifecycleType.FREEZE_ACTION_DEPRECATION_WARNING)
);

// restore the datastream
Expand Down

0 comments on commit dfc9a8e

Please sign in to comment.