Browse Source

Refactor `ShrinkStep` to `ResizeStep` (#133591)

By making the step more generic, we can reuse it in other actions (such
as the upcoming improved force merge action).
Niels Bauman 2 tháng trước cách đây
mục cha
commit
699f4cf909

+ 1 - 1
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OperationMode.java

@@ -22,7 +22,7 @@ public enum OperationMode {
     },
 
     /**
-     * this represents a state where only sensitive actions (like {@link ShrinkStep}) will be executed
+     * this represents a state where only sensitive actions (like {@link ResizeIndexStep}) will be executed
      * until they finish, at which point the operation mode will move to <code>STOPPED</code>.
      */
     STOPPING {

+ 150 - 0
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStep.java

@@ -0,0 +1,150 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.core.ilm;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
+import org.elasticsearch.action.admin.indices.shrink.ResizeType;
+import org.elasticsearch.client.internal.Client;
+import org.elasticsearch.cluster.ClusterStateObserver;
+import org.elasticsearch.cluster.ProjectState;
+import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.cluster.metadata.LifecycleExecutionState;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.unit.ByteSizeValue;
+import org.elasticsearch.core.Nullable;
+import org.elasticsearch.core.TimeValue;
+
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * Resizes an index with the specified settings, using the name that was generated in a previous {@link GenerateUniqueIndexNameStep} step.
+ */
+public class ResizeIndexStep extends AsyncActionStep {
+
+    public static final String SHRINK = "shrink";
+    public static final String CLONE = "clone";
+    private static final Logger logger = LogManager.getLogger(ResizeIndexStep.class);
+
+    private final ResizeType resizeType;
+    private final BiFunction<String, LifecycleExecutionState, String> targetIndexNameSupplier;
+    /** A supplier that takes the index metadata of the <i>original</i> index and returns settings for the target index . */
+    private final Function<IndexMetadata, Settings> targetIndexSettingsSupplier;
+    @Nullable
+    private final ByteSizeValue maxPrimaryShardSize;
+
+    public ResizeIndexStep(
+        StepKey key,
+        StepKey nextStepKey,
+        Client client,
+        ResizeType resizeType,
+        BiFunction<String, LifecycleExecutionState, String> targetIndexNameSupplier,
+        Function<IndexMetadata, Settings> targetIndexSettingsSupplier,
+        @Nullable ByteSizeValue maxPrimaryShardSize
+    ) {
+        super(key, nextStepKey, client);
+        this.resizeType = resizeType;
+        this.targetIndexNameSupplier = targetIndexNameSupplier;
+        this.targetIndexSettingsSupplier = targetIndexSettingsSupplier;
+        this.maxPrimaryShardSize = maxPrimaryShardSize;
+        assert resizeType == ResizeType.SHRINK || maxPrimaryShardSize == null : "maxPrimaryShardSize can only be set for shrink operations";
+    }
+
+    @Override
+    public boolean isRetryable() {
+        return true;
+    }
+
+    @Override
+    public void performAction(
+        IndexMetadata indexMetadata,
+        ProjectState currentState,
+        ClusterStateObserver observer,
+        ActionListener<Void> listener
+    ) {
+        LifecycleExecutionState lifecycleState = indexMetadata.getLifecycleExecutionState();
+        if (lifecycleState.lifecycleDate() == null) {
+            throw new IllegalStateException("source index [" + indexMetadata.getIndex().getName() + "] is missing lifecycle date");
+        }
+
+        final String targetIndexName = targetIndexNameSupplier.apply(indexMetadata.getIndex().getName(), lifecycleState);
+        if (currentState.metadata().index(targetIndexName) != null) {
+            logger.warn(
+                "skipping [{}] step for index [{}] as part of policy [{}] as the target index [{}] already exists",
+                getKey().name(),
+                indexMetadata.getIndex().getName(),
+                indexMetadata.getLifecyclePolicyName(),
+                targetIndexName
+            );
+            listener.onResponse(null);
+            return;
+        }
+
+        Settings relevantTargetSettings = Settings.builder()
+            .put(targetIndexSettingsSupplier.apply(indexMetadata))
+            // We add the skip setting to prevent ILM from processing the shrunken index before the execution state has been copied - which
+            // could happen if the shards of the shrunken index take a long time to allocate.
+            .put(LifecycleSettings.LIFECYCLE_SKIP, true)
+            .build();
+
+        ResizeRequest resizeRequest = new ResizeRequest(targetIndexName, indexMetadata.getIndex().getName()).masterNodeTimeout(
+            TimeValue.MAX_VALUE
+        );
+        resizeRequest.setResizeType(resizeType);
+        resizeRequest.getTargetIndexRequest().settings(relevantTargetSettings);
+        if (resizeType == ResizeType.SHRINK) {
+            resizeRequest.setMaxPrimaryShardSize(maxPrimaryShardSize);
+        }
+
+        // This request does not wait for (successful) completion of the resize operation - it fires-and-forgets.
+        // It's up to a subsequent step to check for the existence of the target index and wait for it to be green.
+        getClient(currentState.projectId()).admin()
+            .indices()
+            .resizeIndex(resizeRequest, listener.delegateFailureAndWrap((l, response) -> l.onResponse(null)));
+
+    }
+
+    public ResizeType getResizeType() {
+        return resizeType;
+    }
+
+    public BiFunction<String, LifecycleExecutionState, String> getTargetIndexNameSupplier() {
+        return targetIndexNameSupplier;
+    }
+
+    public Function<IndexMetadata, Settings> getTargetIndexSettingsSupplier() {
+        return targetIndexSettingsSupplier;
+    }
+
+    public ByteSizeValue getMaxPrimaryShardSize() {
+        return maxPrimaryShardSize;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), resizeType, maxPrimaryShardSize);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ResizeIndexStep other = (ResizeIndexStep) obj;
+        return super.equals(obj)
+            && Objects.equals(resizeType, other.resizeType)
+            && Objects.equals(maxPrimaryShardSize, other.maxPrimaryShardSize);
+    }
+
+}

+ 20 - 2
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkAction.java

@@ -10,6 +10,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.elasticsearch.TransportVersions;
 import org.elasticsearch.action.admin.indices.shrink.ResizeNumberOfShardsCalculator;
+import org.elasticsearch.action.admin.indices.shrink.ResizeType;
 import org.elasticsearch.action.admin.indices.stats.IndexShardStats;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.cluster.metadata.IndexAbstraction;
@@ -173,7 +174,7 @@ public class ShrinkAction implements LifecycleAction {
         StepKey generateShrinkIndexNameKey = new StepKey(phase, NAME, GenerateUniqueIndexNameStep.NAME);
         StepKey setSingleNodeKey = new StepKey(phase, NAME, SetSingleNodeAllocateStep.NAME);
         StepKey allocationRoutedKey = new StepKey(phase, NAME, CheckShrinkReadyStep.NAME);
-        StepKey shrinkKey = new StepKey(phase, NAME, ShrinkStep.NAME);
+        StepKey shrinkKey = new StepKey(phase, NAME, ResizeIndexStep.SHRINK);
         StepKey enoughShardsKey = new StepKey(phase, NAME, ShrunkShardsAllocatedStep.NAME);
         StepKey copyMetadataKey = new StepKey(phase, NAME, CopyExecutionStateStep.NAME);
         StepKey dataStreamCheckBranchingKey = new StepKey(phase, NAME, CONDITIONAL_DATASTREAM_CHECK_KEY);
@@ -267,7 +268,24 @@ public class ShrinkAction implements LifecycleAction {
             new CheckShrinkReadyStep(allocationRoutedKey, shrinkKey),
             setSingleNodeKey
         );
-        ShrinkStep shrink = new ShrinkStep(shrinkKey, enoughShardsKey, client, numberOfShards, maxPrimaryShardSize);
+        ResizeIndexStep shrink = new ResizeIndexStep(
+            shrinkKey,
+            enoughShardsKey,
+            client,
+            ResizeType.SHRINK,
+            ShrinkIndexNameSupplier::getShrinkIndexName,
+            indexMetadata -> {
+                Settings.Builder settingsBuilder = Settings.builder()
+                    .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, indexMetadata.getNumberOfReplicas())
+                    // We need to remove the single node allocation so replicas can be allocated.
+                    .put(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "_id", (String) null);
+                if (numberOfShards != null) {
+                    settingsBuilder.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numberOfShards);
+                }
+                return settingsBuilder.build();
+            },
+            maxPrimaryShardSize
+        );
         // wait until the shrunk index is recovered. we again wait until the configured threshold is breached and if the shrunk index has
         // not successfully recovered until then, we rewind to the "cleanup-shrink-index" step to delete this unsuccessful shrunk index
         // and retry the operation by generating a new shrink index name and attempting to shrink again

+ 0 - 129
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkStep.java

@@ -1,129 +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
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-package org.elasticsearch.xpack.core.ilm;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
-import org.elasticsearch.client.internal.Client;
-import org.elasticsearch.cluster.ClusterStateObserver;
-import org.elasticsearch.cluster.ProjectState;
-import org.elasticsearch.cluster.metadata.IndexMetadata;
-import org.elasticsearch.cluster.metadata.LifecycleExecutionState;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.unit.ByteSizeValue;
-import org.elasticsearch.core.TimeValue;
-
-import java.util.Objects;
-
-import static org.elasticsearch.xpack.core.ilm.ShrinkIndexNameSupplier.getShrinkIndexName;
-
-/**
- * Shrinks an index, using a prefix prepended to the original index name for the name of the shrunken index.
- */
-public class ShrinkStep extends AsyncActionStep {
-    public static final String NAME = "shrink";
-    private static final Logger logger = LogManager.getLogger(ShrinkStep.class);
-
-    private final Integer numberOfShards;
-    private final ByteSizeValue maxPrimaryShardSize;
-
-    public ShrinkStep(StepKey key, StepKey nextStepKey, Client client, Integer numberOfShards, ByteSizeValue maxPrimaryShardSize) {
-        super(key, nextStepKey, client);
-        this.numberOfShards = numberOfShards;
-        this.maxPrimaryShardSize = maxPrimaryShardSize;
-    }
-
-    @Override
-    public boolean isRetryable() {
-        return true;
-    }
-
-    public Integer getNumberOfShards() {
-        return numberOfShards;
-    }
-
-    public ByteSizeValue getMaxPrimaryShardSize() {
-        return maxPrimaryShardSize;
-    }
-
-    @Override
-    public void performAction(
-        IndexMetadata indexMetadata,
-        ProjectState currentState,
-        ClusterStateObserver observer,
-        ActionListener<Void> listener
-    ) {
-        LifecycleExecutionState lifecycleState = indexMetadata.getLifecycleExecutionState();
-        if (lifecycleState.lifecycleDate() == null) {
-            throw new IllegalStateException("source index [" + indexMetadata.getIndex().getName() + "] is missing lifecycle date");
-        }
-
-        String shrunkenIndexName = getShrinkIndexName(indexMetadata.getIndex().getName(), lifecycleState);
-        if (currentState.metadata().index(shrunkenIndexName) != null) {
-            logger.warn(
-                "skipping [{}] step for index [{}] as part of policy [{}] as the shrunk index [{}] already exists",
-                ShrinkStep.NAME,
-                indexMetadata.getIndex().getName(),
-                indexMetadata.getLifecyclePolicyName(),
-                shrunkenIndexName
-            );
-            listener.onResponse(null);
-            return;
-        }
-
-        String policyName = indexMetadata.getLifecyclePolicyName();
-
-        Settings.Builder builder = Settings.builder();
-        // need to remove the single shard, allocation so replicas can be allocated
-        builder.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, indexMetadata.getNumberOfReplicas())
-            .put(LifecycleSettings.LIFECYCLE_NAME, policyName)
-            // We add the skip setting to prevent ILM from processing the shrunken index before the execution state has been copied - which
-            // could happen if the shards of the shrunken index take a long time to allocate.
-            .put(LifecycleSettings.LIFECYCLE_SKIP, true)
-            .put(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "_id", (String) null);
-        if (numberOfShards != null) {
-            builder.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numberOfShards);
-        }
-        Settings relevantTargetSettings = builder.build();
-
-        ResizeRequest resizeRequest = new ResizeRequest(shrunkenIndexName, indexMetadata.getIndex().getName()).masterNodeTimeout(
-            TimeValue.MAX_VALUE
-        );
-        resizeRequest.setMaxPrimaryShardSize(maxPrimaryShardSize);
-        resizeRequest.getTargetIndexRequest().settings(relevantTargetSettings);
-
-        // Hard coding this to true as the resize request was executed and the corresponding cluster change was committed, so the
-        // eventual retry will not be able to succeed anymore (shrunk index was created already)
-        // The next step in the ShrinkAction will wait for the shrunk index to be created and for the shards to be allocated.
-        getClient(currentState.projectId()).admin()
-            .indices()
-            .resizeIndex(resizeRequest, listener.delegateFailureAndWrap((l, response) -> l.onResponse(null)));
-
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(super.hashCode(), numberOfShards, maxPrimaryShardSize);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        ShrinkStep other = (ShrinkStep) obj;
-        return super.equals(obj)
-            && Objects.equals(numberOfShards, other.numberOfShards)
-            && Objects.equals(maxPrimaryShardSize, other.maxPrimaryShardSize);
-    }
-
-}

+ 48 - 36
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkStepTests.java → x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStepTests.java

@@ -10,6 +10,7 @@ import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
 import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
 import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
+import org.elasticsearch.action.admin.indices.shrink.ResizeType;
 import org.elasticsearch.cluster.ProjectState;
 import org.elasticsearch.cluster.metadata.AliasMetadata;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
@@ -29,60 +30,81 @@ import static org.elasticsearch.common.IndexNameGenerator.generateValidIndexName
 import static org.elasticsearch.xpack.core.ilm.ShrinkIndexNameSupplier.SHRUNKEN_INDEX_PREFIX;
 import static org.hamcrest.Matchers.equalTo;
 
-public class ShrinkStepTests extends AbstractStepTestCase<ShrinkStep> {
+public class ResizeIndexStepTests extends AbstractStepTestCase<ResizeIndexStep> {
 
     @Override
-    public ShrinkStep createRandomInstance() {
+    public ResizeIndexStep createRandomInstance() {
         StepKey stepKey = randomStepKey();
         StepKey nextStepKey = randomStepKey();
-        Integer numberOfShards = null;
+        ResizeType resizeType = randomFrom(ResizeType.values());
+        Settings.Builder settings = Settings.builder();
         ByteSizeValue maxPrimaryShardSize = null;
-        if (randomBoolean()) {
-            numberOfShards = randomIntBetween(1, 20);
+        // Only shrink supports max_primary_shard_size, so if we pick shrink we sometimes set it, otherwise we always
+        // set number_of_shards.
+        if (resizeType != ResizeType.SHRINK || randomBoolean()) {
+            settings.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 20));
         } else {
             maxPrimaryShardSize = ByteSizeValue.ofBytes(between(1, 100));
         }
-        return new ShrinkStep(stepKey, nextStepKey, client, numberOfShards, maxPrimaryShardSize);
+        return new ResizeIndexStep(
+            stepKey,
+            nextStepKey,
+            client,
+            resizeType,
+            (index, state) -> randomAlphaOfLength(5) + index,
+            indexMetadata -> settings.build(),
+            maxPrimaryShardSize
+        );
     }
 
     @Override
-    public ShrinkStep mutateInstance(ShrinkStep instance) {
+    public ResizeIndexStep mutateInstance(ResizeIndexStep instance) {
         StepKey key = instance.getKey();
         StepKey nextKey = instance.getNextStepKey();
-        Integer numberOfShards = instance.getNumberOfShards();
+        ResizeType resizeType = instance.getResizeType();
         ByteSizeValue maxPrimaryShardSize = instance.getMaxPrimaryShardSize();
 
         switch (between(0, 2)) {
             case 0 -> key = new StepKey(key.phase(), key.action(), key.name() + randomAlphaOfLength(5));
             case 1 -> nextKey = new StepKey(nextKey.phase(), nextKey.action(), nextKey.name() + randomAlphaOfLength(5));
             case 2 -> {
-                if (numberOfShards != null) {
-                    numberOfShards = numberOfShards + 1;
-                }
-                if (maxPrimaryShardSize != null) {
-                    maxPrimaryShardSize = ByteSizeValue.ofBytes(maxPrimaryShardSize.getBytes() + 1);
+                if (resizeType != ResizeType.SHRINK || randomBoolean()) {
+                    resizeType = randomValueOtherThan(resizeType, () -> randomFrom(ResizeType.values()));
+                    maxPrimaryShardSize = null;
+                } else {
+                    maxPrimaryShardSize = randomValueOtherThan(maxPrimaryShardSize, () -> ByteSizeValue.ofBytes(between(1, 100)));
                 }
             }
             default -> throw new AssertionError("Illegal randomisation branch");
         }
 
-        return new ShrinkStep(key, nextKey, instance.getClientWithoutProject(), numberOfShards, maxPrimaryShardSize);
+        return new ResizeIndexStep(
+            key,
+            nextKey,
+            instance.getClientWithoutProject(),
+            resizeType,
+            instance.getTargetIndexNameSupplier(),
+            instance.getTargetIndexSettingsSupplier(),
+            maxPrimaryShardSize
+        );
     }
 
     @Override
-    public ShrinkStep copyInstance(ShrinkStep instance) {
-        return new ShrinkStep(
+    public ResizeIndexStep copyInstance(ResizeIndexStep instance) {
+        return new ResizeIndexStep(
             instance.getKey(),
             instance.getNextStepKey(),
             instance.getClientWithoutProject(),
-            instance.getNumberOfShards(),
+            instance.getResizeType(),
+            instance.getTargetIndexNameSupplier(),
+            instance.getTargetIndexSettingsSupplier(),
             instance.getMaxPrimaryShardSize()
         );
     }
 
     public void testPerformAction() throws Exception {
         String lifecycleName = randomAlphaOfLength(5);
-        ShrinkStep step = createRandomInstance();
+        ResizeIndexStep step = createRandomInstance();
         LifecycleExecutionState.Builder lifecycleState = LifecycleExecutionState.builder();
         lifecycleState.setPhase(step.getKey().phase());
         lifecycleState.setAction(step.getKey().action());
@@ -103,22 +125,12 @@ public class ShrinkStepTests extends AbstractStepTestCase<ShrinkStep> {
             assertThat(request.getSourceIndex(), equalTo(sourceIndexMetadata.getIndex().getName()));
             assertThat(request.getTargetIndexRequest().aliases(), equalTo(Set.of()));
 
-            Settings.Builder builder = Settings.builder();
-            builder.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, sourceIndexMetadata.getNumberOfReplicas())
-                .put(LifecycleSettings.LIFECYCLE_NAME, lifecycleName)
+            Settings expectedSettings = Settings.builder()
+                .put(step.getTargetIndexSettingsSupplier().apply(null))
                 .put(LifecycleSettings.LIFECYCLE_SKIP, true)
-                .put(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "_id", (String) null);
-            if (step.getNumberOfShards() != null) {
-                builder.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, step.getNumberOfShards());
-            }
-            assertThat(request.getTargetIndexRequest().settings(), equalTo(builder.build()));
-            if (step.getNumberOfShards() != null) {
-                assertThat(
-                    request.getTargetIndexRequest().settings().getAsInt(IndexMetadata.SETTING_NUMBER_OF_SHARDS, -1),
-                    equalTo(step.getNumberOfShards())
-                );
-            }
-            request.setMaxPrimaryShardSize(step.getMaxPrimaryShardSize());
+                .build();
+            assertThat(request.getTargetIndexRequest().settings(), equalTo(expectedSettings));
+            assertThat(request.getMaxPrimaryShardSize(), equalTo(step.getMaxPrimaryShardSize()));
             listener.onResponse(new CreateIndexResponse(true, true, sourceIndexMetadata.getIndex().getName()));
             return null;
         }).when(indicesClient).resizeIndex(Mockito.any(), Mockito.any());
@@ -136,7 +148,7 @@ public class ShrinkStepTests extends AbstractStepTestCase<ShrinkStep> {
     public void testPerformActionShrunkenIndexExists() throws Exception {
         String sourceIndexName = randomAlphaOfLength(10);
         String lifecycleName = randomAlphaOfLength(5);
-        ShrinkStep step = createRandomInstance();
+        ResizeIndexStep step = createRandomInstance();
         LifecycleExecutionState.Builder lifecycleState = LifecycleExecutionState.builder();
         lifecycleState.setPhase(step.getKey().phase());
         lifecycleState.setAction(step.getKey().action());
@@ -180,7 +192,7 @@ public class ShrinkStepTests extends AbstractStepTestCase<ShrinkStep> {
             .numberOfShards(randomIntBetween(1, 5))
             .numberOfReplicas(randomIntBetween(0, 5))
             .build();
-        ShrinkStep step = createRandomInstance();
+        ResizeIndexStep step = createRandomInstance();
 
         Mockito.doAnswer(invocation -> {
             @SuppressWarnings("unchecked")
@@ -209,7 +221,7 @@ public class ShrinkStepTests extends AbstractStepTestCase<ShrinkStep> {
             .numberOfReplicas(randomIntBetween(0, 5))
             .build();
         Exception exception = new RuntimeException();
-        ShrinkStep step = createRandomInstance();
+        ResizeIndexStep step = createRandomInstance();
 
         Mockito.doAnswer(invocation -> {
             @SuppressWarnings("unchecked")

+ 2 - 2
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkActionTests.java

@@ -290,7 +290,7 @@ public class ShrinkActionTests extends AbstractActionTestCase<ShrinkAction> {
         StepKey generateShrinkIndexNameKey = new StepKey(phase, ShrinkAction.NAME, GenerateUniqueIndexNameStep.NAME);
         StepKey setSingleNodeKey = new StepKey(phase, ShrinkAction.NAME, SetSingleNodeAllocateStep.NAME);
         StepKey allocationRoutedKey = new StepKey(phase, ShrinkAction.NAME, CheckShrinkReadyStep.NAME);
-        StepKey shrinkKey = new StepKey(phase, ShrinkAction.NAME, ShrinkStep.NAME);
+        StepKey shrinkKey = new StepKey(phase, ShrinkAction.NAME, ResizeIndexStep.SHRINK);
         StepKey enoughShardsKey = new StepKey(phase, ShrinkAction.NAME, ShrunkShardsAllocatedStep.NAME);
         StepKey copyMetadataKey = new StepKey(phase, ShrinkAction.NAME, CopyExecutionStateStep.NAME);
         StepKey dataStreamCheckBranchingKey = new StepKey(phase, ShrinkAction.NAME, ShrinkAction.CONDITIONAL_DATASTREAM_CHECK_KEY);
@@ -347,7 +347,7 @@ public class ShrinkActionTests extends AbstractActionTestCase<ShrinkAction> {
         assertThat(steps.get(9).getKey(), equalTo(allocationRoutedKey));
         assertThat(steps.get(9).getNextStepKey(), equalTo(shrinkKey));
 
-        assertTrue(steps.get(10) instanceof ShrinkStep);
+        assertTrue(steps.get(10) instanceof ResizeIndexStep);
         assertThat(steps.get(10).getKey(), equalTo(shrinkKey));
         assertThat(steps.get(10).getNextStepKey(), equalTo(enoughShardsKey));
 

+ 3 - 3
x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleService.java

@@ -48,9 +48,9 @@ import org.elasticsearch.xpack.core.ilm.LifecyclePolicy;
 import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
 import org.elasticsearch.xpack.core.ilm.OperationMode;
 import org.elasticsearch.xpack.core.ilm.OperationModeUpdateTask;
+import org.elasticsearch.xpack.core.ilm.ResizeIndexStep;
 import org.elasticsearch.xpack.core.ilm.SetSingleNodeAllocateStep;
 import org.elasticsearch.xpack.core.ilm.ShrinkAction;
-import org.elasticsearch.xpack.core.ilm.ShrinkStep;
 import org.elasticsearch.xpack.core.ilm.ShrunkShardsAllocatedStep;
 import org.elasticsearch.xpack.core.ilm.Step;
 import org.elasticsearch.xpack.core.ilm.Step.StepKey;
@@ -84,7 +84,7 @@ public class IndexLifecycleService
         IndexEventListener,
         ShutdownAwarePlugin {
     private static final Logger logger = LogManager.getLogger(IndexLifecycleService.class);
-    private static final Set<String> IGNORE_STEPS_MAINTENANCE_REQUESTED = Set.of(ShrinkStep.NAME, DownsampleStep.NAME);
+    private static final Set<String> IGNORE_STEPS_MAINTENANCE_REQUESTED = Set.of(ResizeIndexStep.SHRINK, DownsampleStep.NAME);
     private volatile boolean isMaster = false;
     private volatile TimeValue pollInterval;
 
@@ -618,7 +618,7 @@ public class IndexLifecycleService
                     String step = indexToMetadata.getValue().getLifecycleExecutionState().step();
                     return SetSingleNodeAllocateStep.NAME.equals(step)
                         || CheckShrinkReadyStep.NAME.equals(step)
-                        || ShrinkStep.NAME.equals(step)
+                        || ResizeIndexStep.SHRINK.equals(step)
                         || ShrunkShardsAllocatedStep.NAME.equals(step);
                 })
                 // Only look at indices where the node picked for the shrink is the node marked as shutting down

+ 4 - 4
x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java

@@ -50,9 +50,9 @@ import org.elasticsearch.xpack.core.ilm.MockAction;
 import org.elasticsearch.xpack.core.ilm.OperationMode;
 import org.elasticsearch.xpack.core.ilm.OperationModeUpdateTask;
 import org.elasticsearch.xpack.core.ilm.Phase;
+import org.elasticsearch.xpack.core.ilm.ResizeIndexStep;
 import org.elasticsearch.xpack.core.ilm.SetSingleNodeAllocateStep;
 import org.elasticsearch.xpack.core.ilm.ShrinkAction;
-import org.elasticsearch.xpack.core.ilm.ShrinkStep;
 import org.elasticsearch.xpack.core.ilm.ShrunkShardsAllocatedStep;
 import org.elasticsearch.xpack.core.ilm.Step;
 import org.junit.After;
@@ -184,7 +184,7 @@ public class IndexLifecycleServiceTests extends ESTestCase {
     }
 
     public void testRequestedStopOnShrink() {
-        Step.StepKey mockShrinkStep = new Step.StepKey(randomAlphaOfLength(4), ShrinkAction.NAME, ShrinkStep.NAME);
+        Step.StepKey mockShrinkStep = new Step.StepKey(randomAlphaOfLength(4), ShrinkAction.NAME, ResizeIndexStep.SHRINK);
         String policyName = randomAlphaOfLengthBetween(1, 20);
         IndexLifecycleRunnerTests.MockClusterStateActionStep mockStep = new IndexLifecycleRunnerTests.MockClusterStateActionStep(
             mockShrinkStep,
@@ -232,7 +232,7 @@ public class IndexLifecycleServiceTests extends ESTestCase {
         action.toSteps(mock(Client.class), "warm", randomStepKey())
             .stream()
             .map(sk -> sk.getKey().name())
-            .filter(name -> name.equals(ShrinkStep.NAME) == false)
+            .filter(name -> name.equals(ResizeIndexStep.SHRINK) == false)
             .forEach(this::verifyCanStopWithStep);
     }
 
@@ -563,7 +563,7 @@ public class IndexLifecycleServiceTests extends ESTestCase {
                             randomFrom(
                                 SetSingleNodeAllocateStep.NAME,
                                 CheckShrinkReadyStep.NAME,
-                                ShrinkStep.NAME,
+                                ResizeIndexStep.SHRINK,
                                 ShrunkShardsAllocatedStep.NAME
                             )
                         )

+ 34 - 15
x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistryTests.java

@@ -30,8 +30,8 @@ import org.elasticsearch.xpack.core.ilm.MockStep;
 import org.elasticsearch.xpack.core.ilm.OperationMode;
 import org.elasticsearch.xpack.core.ilm.Phase;
 import org.elasticsearch.xpack.core.ilm.PhaseExecutionInfo;
+import org.elasticsearch.xpack.core.ilm.ResizeIndexStep;
 import org.elasticsearch.xpack.core.ilm.ShrinkAction;
-import org.elasticsearch.xpack.core.ilm.ShrinkStep;
 import org.elasticsearch.xpack.core.ilm.Step;
 import org.mockito.Mockito;
 
@@ -301,7 +301,6 @@ public class PolicyStepsRegistryTests extends ESTestCase {
         LifecyclePolicy updatedPolicy = new LifecyclePolicy(policyName, phases);
         logger.info("--> policy: {}", newPolicy);
         logger.info("--> updated policy: {}", updatedPolicy);
-        List<Step> policySteps = newPolicy.toSteps(client, null);
         Map<String, String> headers = new HashMap<>();
         if (randomBoolean()) {
             headers.put(randomAlphaOfLength(10), randomAlphaOfLength(10));
@@ -315,17 +314,17 @@ public class PolicyStepsRegistryTests extends ESTestCase {
         LifecycleExecutionState.Builder lifecycleState = LifecycleExecutionState.builder();
         lifecycleState.setPhase("warm");
         lifecycleState.setPhaseDefinition(phaseJson);
+        IndexMetadata indexMetadata = IndexMetadata.builder("test")
+            .settings(
+                indexSettings(1, 0).put("index.uuid", "uuid")
+                    .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current())
+                    .put(LifecycleSettings.LIFECYCLE_NAME, policyName)
+            )
+            .putCustom(ILM_CUSTOM_METADATA_KEY, lifecycleState.build().asMap())
+            .build();
         ProjectMetadata currentProject = ProjectMetadata.builder(randomProjectIdOrDefault())
             .putCustom(IndexLifecycleMetadata.TYPE, lifecycleMetadata)
-            .put(
-                IndexMetadata.builder("test")
-                    .settings(
-                        indexSettings(1, 0).put("index.uuid", "uuid")
-                            .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current())
-                            .put(LifecycleSettings.LIFECYCLE_NAME, policyName)
-                    )
-                    .putCustom(ILM_CUSTOM_METADATA_KEY, lifecycleState.build().asMap())
-            )
+            .put(indexMetadata, false)
             .build();
 
         // start with empty registry
@@ -342,8 +341,18 @@ public class PolicyStepsRegistryTests extends ESTestCase {
             .get()
             .getValue();
         Step gotStep = registry.getStep(currentProject.index(index), shrinkStep.getKey());
-        assertThat(((ShrinkStep) shrinkStep).getNumberOfShards(), equalTo(1));
-        assertThat(((ShrinkStep) gotStep).getNumberOfShards(), equalTo(1));
+        assertThat(
+            ((ResizeIndexStep) shrinkStep).getTargetIndexSettingsSupplier()
+                .apply(indexMetadata)
+                .getAsInt(IndexMetadata.SETTING_NUMBER_OF_SHARDS, -1),
+            equalTo(1)
+        );
+        assertThat(
+            ((ResizeIndexStep) gotStep).getTargetIndexSettingsSupplier()
+                .apply(indexMetadata)
+                .getAsInt(IndexMetadata.SETTING_NUMBER_OF_SHARDS, -1),
+            equalTo(1)
+        );
 
         // Update the policy with the new policy, but keep the phase the same
         policyMap = Map.of(
@@ -364,8 +373,18 @@ public class PolicyStepsRegistryTests extends ESTestCase {
             .get()
             .getValue();
         gotStep = registry.getStep(currentProject.index(index), shrinkStep.getKey());
-        assertThat(((ShrinkStep) shrinkStep).getNumberOfShards(), equalTo(2));
-        assertThat(((ShrinkStep) gotStep).getNumberOfShards(), equalTo(1));
+        assertThat(
+            ((ResizeIndexStep) shrinkStep).getTargetIndexSettingsSupplier()
+                .apply(indexMetadata)
+                .getAsInt(IndexMetadata.SETTING_NUMBER_OF_SHARDS, -1),
+            equalTo(2)
+        );
+        assertThat(
+            ((ResizeIndexStep) gotStep).getTargetIndexSettingsSupplier()
+                .apply(indexMetadata)
+                .getAsInt(IndexMetadata.SETTING_NUMBER_OF_SHARDS, -1),
+            equalTo(1)
+        );
     }
 
     public void testGetStepMultithreaded() throws Exception {

+ 4 - 4
x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java

@@ -54,8 +54,8 @@ import org.elasticsearch.test.gateway.TestGatewayAllocator;
 import org.elasticsearch.xpack.core.ilm.ErrorStep;
 import org.elasticsearch.xpack.core.ilm.LifecycleOperationMetadata;
 import org.elasticsearch.xpack.core.ilm.OperationMode;
+import org.elasticsearch.xpack.core.ilm.ResizeIndexStep;
 import org.elasticsearch.xpack.core.ilm.ShrinkAction;
-import org.elasticsearch.xpack.core.ilm.ShrinkStep;
 import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType;
 import org.hamcrest.Matcher;
 import org.junit.Before;
@@ -694,7 +694,7 @@ public class TransportGetShutdownStatusActionTests extends ESTestCase {
     public void testIlmShrinkingIndexAvoidsStall() {
         LifecycleExecutionState executionState = LifecycleExecutionState.builder()
             .setAction(ShrinkAction.NAME)
-            .setStep(ShrinkStep.NAME)
+            .setStep(ResizeIndexStep.SHRINK)
             .setPhase(randomFrom("hot", "warm"))
             .build();
         checkStalledShardWithIlmState(executionState, OperationMode.RUNNING, SingleNodeShutdownMetadata.Status.IN_PROGRESS);
@@ -703,7 +703,7 @@ public class TransportGetShutdownStatusActionTests extends ESTestCase {
     public void testIlmShrinkingWithIlmStoppingIndexAvoidsStall() {
         LifecycleExecutionState executionState = LifecycleExecutionState.builder()
             .setAction(ShrinkAction.NAME)
-            .setStep(ShrinkStep.NAME)
+            .setStep(ResizeIndexStep.SHRINK)
             .build();
         checkStalledShardWithIlmState(executionState, OperationMode.STOPPING, SingleNodeShutdownMetadata.Status.IN_PROGRESS);
     }
@@ -711,7 +711,7 @@ public class TransportGetShutdownStatusActionTests extends ESTestCase {
     public void testIlmShrinkingButIlmStoppedDoesNotAvoidStall() {
         LifecycleExecutionState executionState = LifecycleExecutionState.builder()
             .setAction(ShrinkAction.NAME)
-            .setStep(ShrinkStep.NAME)
+            .setStep(ResizeIndexStep.SHRINK)
             .build();
         checkStalledShardWithIlmState(executionState, OperationMode.STOPPED, SingleNodeShutdownMetadata.Status.STALLED);
     }