diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OperationMode.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OperationMode.java index 95a1bf8493e42..ff4e11c998305 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OperationMode.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OperationMode.java @@ -22,7 +22,7 @@ public boolean isValidChange(OperationMode nextMode) { }, /** - * 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 STOPPED. */ STOPPING { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStep.java new file mode 100644 index 0000000000000..847647b0cd5d3 --- /dev/null +++ b/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 targetIndexNameSupplier; + /** A supplier that takes the index metadata of the original index and returns settings for the target index . */ + private final Function targetIndexSettingsSupplier; + @Nullable + private final ByteSizeValue maxPrimaryShardSize; + + public ResizeIndexStep( + StepKey key, + StepKey nextStepKey, + Client client, + ResizeType resizeType, + BiFunction targetIndexNameSupplier, + Function 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 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 getTargetIndexNameSupplier() { + return targetIndexNameSupplier; + } + + public Function 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); + } + +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkAction.java index 7ec2cdeb06aa5..177cd5badcfb1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkAction.java @@ -10,6 +10,7 @@ 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 List toSteps(Client client, String phase, Step.StepKey nextStepKey) 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 List toSteps(Client client, String phase, Step.StepKey nextStepKey) 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 diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkStep.java deleted file mode 100644 index d8bb60d5ee5e5..0000000000000 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkStep.java +++ /dev/null @@ -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 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); - } - -} diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStepTests.java similarity index 79% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkStepTests.java rename to x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStepTests.java index d1b7e5d3e24f1..9fb230885a4b9 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ResizeIndexStepTests.java @@ -10,6 +10,7 @@ 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.xpack.core.ilm.ShrinkIndexNameSupplier.SHRUNKEN_INDEX_PREFIX; import static org.hamcrest.Matchers.equalTo; -public class ShrinkStepTests extends AbstractStepTestCase { +public class ResizeIndexStepTests extends AbstractStepTestCase { @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 void testPerformAction() throws Exception { 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 void testPerformAction() throws Exception { 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 void testPerformActionIsCompleteForUnAckedRequests() throws Exception { .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 void testPerformActionFailure() throws Exception { .numberOfReplicas(randomIntBetween(0, 5)) .build(); Exception exception = new RuntimeException(); - ShrinkStep step = createRandomInstance(); + ResizeIndexStep step = createRandomInstance(); Mockito.doAnswer(invocation -> { @SuppressWarnings("unchecked") diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkActionTests.java index e7bc6e200a6db..75e92198a984a 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkActionTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/ShrinkActionTests.java @@ -290,7 +290,7 @@ public void testToSteps() { 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 void testToSteps() { 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)); diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleService.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleService.java index 1dae42956dec8..8e5ede13128f9 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleService.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleService.java @@ -48,9 +48,9 @@ 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 IGNORE_STEPS_MAINTENANCE_REQUESTED = Set.of(ShrinkStep.NAME, DownsampleStep.NAME); + private static final Set IGNORE_STEPS_MAINTENANCE_REQUESTED = Set.of(ResizeIndexStep.SHRINK, DownsampleStep.NAME); private volatile boolean isMaster = false; private volatile TimeValue pollInterval; @@ -618,7 +618,7 @@ static boolean hasIndicesInDangerousStepForNodeShutdown(ClusterState state, Stri 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 diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java index 61eb44ee5497f..c09a247b2dfc6 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleServiceTests.java @@ -50,9 +50,9 @@ 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 void testStoppedModeSkip() { } 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 void testRequestedStopInShrinkActionButNotShrinkStep() { 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 void testHasIndicesInDangerousStepForNodeShutdown() { randomFrom( SetSingleNodeAllocateStep.NAME, CheckShrinkReadyStep.NAME, - ShrinkStep.NAME, + ResizeIndexStep.SHRINK, ShrunkShardsAllocatedStep.NAME ) ) diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistryTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistryTests.java index 78aa4117958c8..67828e8252462 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistryTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistryTests.java @@ -30,8 +30,8 @@ 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 void testUpdatePolicyButNoPhaseChangeIndexStepsDontChange() throws Except LifecyclePolicy updatedPolicy = new LifecyclePolicy(policyName, phases); logger.info("--> policy: {}", newPolicy); logger.info("--> updated policy: {}", updatedPolicy); - List policySteps = newPolicy.toSteps(client, null); Map headers = new HashMap<>(); if (randomBoolean()) { headers.put(randomAlphaOfLength(10), randomAlphaOfLength(10)); @@ -315,17 +314,17 @@ public void testUpdatePolicyButNoPhaseChangeIndexStepsDontChange() throws Except 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 void testUpdatePolicyButNoPhaseChangeIndexStepsDontChange() throws Except .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 void testUpdatePolicyButNoPhaseChangeIndexStepsDontChange() throws Except .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 { diff --git a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java index c8f1d8b58a490..917eb59922962 100644 --- a/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java +++ b/x-pack/plugin/shutdown/src/test/java/org/elasticsearch/xpack/shutdown/TransportGetShutdownStatusActionTests.java @@ -54,8 +54,8 @@ 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 void testExplainThrottled() { 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 void testIlmShrinkingIndexAvoidsStall() { 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 void testIlmShrinkingWithIlmStoppingIndexAvoidsStall() { public void testIlmShrinkingButIlmStoppedDoesNotAvoidStall() { LifecycleExecutionState executionState = LifecycleExecutionState.builder() .setAction(ShrinkAction.NAME) - .setStep(ShrinkStep.NAME) + .setStep(ResizeIndexStep.SHRINK) .build(); checkStalledShardWithIlmState(executionState, OperationMode.STOPPED, SingleNodeShutdownMetadata.Status.STALLED); }