diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UnfollowAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UnfollowAction.java index 1b6db85bc6f12..a09926aa07527 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UnfollowAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UnfollowAction.java @@ -8,6 +8,7 @@ import org.elasticsearch.client.Client; import org.elasticsearch.cluster.health.ClusterHealthStatus; +import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -19,6 +20,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Map; /** * Converts a CCR following index into a normal, standalone index, once the index is ready to be safely separated. @@ -34,11 +36,13 @@ public final class UnfollowAction implements LifecycleAction { public static final String NAME = "unfollow"; public static final String CCR_METADATA_KEY = "ccr"; static final String OPEN_FOLLOWER_INDEX_STEP_NAME = "open-follower-index"; + static final String CONDITIONAL_UNFOLLOW_STEP = BranchingStep.NAME + "-check-unfollow-prerequisites"; public UnfollowAction() {} @Override public List toSteps(Client client, String phase, StepKey nextStepKey) { + StepKey preUnfollowKey = new StepKey(phase, NAME, CONDITIONAL_UNFOLLOW_STEP); StepKey indexingComplete = new StepKey(phase, NAME, WaitForIndexingCompleteStep.NAME); StepKey waitForFollowShardTasks = new StepKey(phase, NAME, WaitForFollowShardTasksStep.NAME); StepKey pauseFollowerIndex = new StepKey(phase, NAME, PauseFollowerIndexStep.NAME); @@ -49,6 +53,13 @@ public List toSteps(Client client, String phase, StepKey nextStepKey) { StepKey openFollowerIndex = new StepKey(phase, NAME, OPEN_FOLLOWER_INDEX_STEP_NAME); StepKey waitForYellowStep = new StepKey(phase, NAME, WaitForIndexColorStep.NAME); + BranchingStep conditionalSkipUnfollowStep = new BranchingStep(preUnfollowKey, indexingComplete, nextStepKey, + (index, clusterState) -> { + IndexMetadata followerIndex = clusterState.metadata().index(index); + Map customIndexMetadata = followerIndex.getCustomData(CCR_METADATA_KEY); + // if the index has no CCR metadata we'll skip the unfollow action completely + return customIndexMetadata == null; + }); WaitForIndexingCompleteStep step1 = new WaitForIndexingCompleteStep(indexingComplete, waitForFollowShardTasks); WaitForFollowShardTasksStep step2 = new WaitForFollowShardTasksStep(waitForFollowShardTasks, pauseFollowerIndex, client); PauseFollowerIndexStep step3 = new PauseFollowerIndexStep(pauseFollowerIndex, closeFollowerIndex, client); @@ -56,7 +67,7 @@ public List toSteps(Client client, String phase, StepKey nextStepKey) { UnfollowFollowerIndexStep step5 = new UnfollowFollowerIndexStep(unfollowFollowerIndex, openFollowerIndex, client); OpenIndexStep step6 = new OpenIndexStep(openFollowerIndex, waitForYellowStep, client); WaitForIndexColorStep step7 = new WaitForIndexColorStep(waitForYellowStep, nextStepKey, ClusterHealthStatus.YELLOW); - return Arrays.asList(step1, step2, step3, step4, step5, step6, step7); + return Arrays.asList(conditionalSkipUnfollowStep, step1, step2, step3, step4, step5, step6, step7); } @Override diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/UnfollowActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/UnfollowActionTests.java index 8dae8948c3c63..a7e613a60a3e5 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/UnfollowActionTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/UnfollowActionTests.java @@ -43,43 +43,47 @@ public void testToSteps() { randomAlphaOfLengthBetween(1, 10)); List steps = action.toSteps(null, phase, nextStepKey); assertThat(steps, notNullValue()); - assertThat(steps.size(), equalTo(7)); - - StepKey expectedFirstStepKey = new StepKey(phase, UnfollowAction.NAME, WaitForIndexingCompleteStep.NAME); - StepKey expectedSecondStepKey = new StepKey(phase, UnfollowAction.NAME, WaitForFollowShardTasksStep.NAME); - StepKey expectedThirdStepKey = new StepKey(phase, UnfollowAction.NAME, PauseFollowerIndexStep.NAME); - StepKey expectedFourthStepKey = new StepKey(phase, UnfollowAction.NAME, CloseFollowerIndexStep.NAME); - StepKey expectedFifthStepKey = new StepKey(phase, UnfollowAction.NAME, UnfollowFollowerIndexStep.NAME); - StepKey expectedSixthStepKey = new StepKey(phase, UnfollowAction.NAME, OPEN_FOLLOWER_INDEX_STEP_NAME); - StepKey expectedSeventhStepKey = new StepKey(phase, UnfollowAction.NAME, WaitForIndexColorStep.NAME); - - WaitForIndexingCompleteStep firstStep = (WaitForIndexingCompleteStep) steps.get(0); + assertThat(steps.size(), equalTo(8)); + + StepKey expectedFirstStepKey = new StepKey(phase, UnfollowAction.NAME, UnfollowAction.CONDITIONAL_UNFOLLOW_STEP); + StepKey expectedSecondStepKey = new StepKey(phase, UnfollowAction.NAME, WaitForIndexingCompleteStep.NAME); + StepKey expectedThirdStepKey = new StepKey(phase, UnfollowAction.NAME, WaitForFollowShardTasksStep.NAME); + StepKey expectedFourthStepKey = new StepKey(phase, UnfollowAction.NAME, PauseFollowerIndexStep.NAME); + StepKey expectedFifthStepKey = new StepKey(phase, UnfollowAction.NAME, CloseFollowerIndexStep.NAME); + StepKey expectedSixthStepKey = new StepKey(phase, UnfollowAction.NAME, UnfollowFollowerIndexStep.NAME); + StepKey expectedSeventhStepKey = new StepKey(phase, UnfollowAction.NAME, OPEN_FOLLOWER_INDEX_STEP_NAME); + StepKey expectedEighthStepKey = new StepKey(phase, UnfollowAction.NAME, WaitForIndexColorStep.NAME); + + BranchingStep firstStep = (BranchingStep) steps.get(0); assertThat(firstStep.getKey(), equalTo(expectedFirstStepKey)); - assertThat(firstStep.getNextStepKey(), equalTo(expectedSecondStepKey)); - WaitForFollowShardTasksStep secondStep = (WaitForFollowShardTasksStep) steps.get(1); + WaitForIndexingCompleteStep secondStep = (WaitForIndexingCompleteStep) steps.get(1); assertThat(secondStep.getKey(), equalTo(expectedSecondStepKey)); assertThat(secondStep.getNextStepKey(), equalTo(expectedThirdStepKey)); - PauseFollowerIndexStep thirdStep = (PauseFollowerIndexStep) steps.get(2); + WaitForFollowShardTasksStep thirdStep = (WaitForFollowShardTasksStep) steps.get(2); assertThat(thirdStep.getKey(), equalTo(expectedThirdStepKey)); assertThat(thirdStep.getNextStepKey(), equalTo(expectedFourthStepKey)); - CloseFollowerIndexStep fourthStep = (CloseFollowerIndexStep) steps.get(3); + PauseFollowerIndexStep fourthStep = (PauseFollowerIndexStep) steps.get(3); assertThat(fourthStep.getKey(), equalTo(expectedFourthStepKey)); assertThat(fourthStep.getNextStepKey(), equalTo(expectedFifthStepKey)); - UnfollowFollowerIndexStep fifthStep = (UnfollowFollowerIndexStep) steps.get(4); + CloseFollowerIndexStep fifthStep = (CloseFollowerIndexStep) steps.get(4); assertThat(fifthStep.getKey(), equalTo(expectedFifthStepKey)); assertThat(fifthStep.getNextStepKey(), equalTo(expectedSixthStepKey)); - OpenIndexStep sixthStep = (OpenIndexStep) steps.get(5); + UnfollowFollowerIndexStep sixthStep = (UnfollowFollowerIndexStep) steps.get(5); assertThat(sixthStep.getKey(), equalTo(expectedSixthStepKey)); assertThat(sixthStep.getNextStepKey(), equalTo(expectedSeventhStepKey)); - WaitForIndexColorStep seventhStep = (WaitForIndexColorStep) steps.get(6); - assertThat(seventhStep.getColor(), is(ClusterHealthStatus.YELLOW)); + OpenIndexStep seventhStep = (OpenIndexStep) steps.get(6); assertThat(seventhStep.getKey(), equalTo(expectedSeventhStepKey)); - assertThat(seventhStep.getNextStepKey(), equalTo(nextStepKey)); + assertThat(seventhStep.getNextStepKey(), equalTo(expectedEighthStepKey)); + + WaitForIndexColorStep eighthStep = (WaitForIndexColorStep) steps.get(7); + assertThat(eighthStep.getColor(), is(ClusterHealthStatus.YELLOW)); + assertThat(eighthStep.getKey(), equalTo(expectedEighthStepKey)); + assertThat(eighthStep.getNextStepKey(), equalTo(nextStepKey)); } } diff --git a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index de2dd400e4e54..00a479dbb3baf 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -991,13 +991,6 @@ public void testHistoryIsWrittenWithSuccess() throws Exception { assertBusy(() -> assertThat(getStepKeyForIndex(client(), index + "-1"), equalTo(PhaseCompleteStep.finalStep("hot").getKey()))); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "wait-for-indexing-complete"), 30, TimeUnit.SECONDS); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "wait-for-follow-shard-tasks"), 30, TimeUnit.SECONDS); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "pause-follower-index"), 30, TimeUnit.SECONDS); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "close-follower-index"), 30, TimeUnit.SECONDS); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "unfollow-follower-index"), 30, TimeUnit.SECONDS); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "open-follower-index"), 30, TimeUnit.SECONDS); - assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "wait-for-index-color"), 30, TimeUnit.SECONDS); assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "check-rollover-ready"), 30, TimeUnit.SECONDS); assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "attempt-rollover"), 30, TimeUnit.SECONDS); assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "set-indexing-complete"), 30, TimeUnit.SECONDS);