Replace PhaseAfterStep with PhaseCompleteStep (#33398)

This removes `PhaseAfterStep` in favor of a new `PhaseCompleteStep`. This step
in only a marker that the `LifecyclePolicyRunner` needs to halt until the time
indicated for entering the next phase.

This also fixes a bug where phase times were encapsulated into the policy
instead of dynamically adjusting to policy changes.

Supersedes #33140, which it replaces
Relates to #29823
This commit is contained in:
Lee Hinman 2018-09-05 16:37:45 -06:00 committed by GitHub
parent 8b8ff2bc6e
commit 96d515e3f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 250 additions and 287 deletions

View File

@ -145,35 +145,39 @@ public class IndexLifecycleIT extends ESRestHighLevelClientTestCase {
highLevelClient().indexLifecycle()::putLifecyclePolicyAsync);
assertTrue(putResponse.isAcknowledged());
createIndex("foo", Settings.builder().put("index.lifecycle.name", policy.getName()).build());
createIndex("baz", Settings.builder().put("index.lifecycle.name", policy.getName()).build());
createIndex("foo-01", Settings.builder().put("index.lifecycle.name", policy.getName())
.put("index.lifecycle.rollover_alias", "foo-alias").build(), "", "\"foo-alias\" : {}");
createIndex("baz-01", Settings.builder().put("index.lifecycle.name", policy.getName())
.put("index.lifecycle.rollover_alias", "baz-alias").build(), "", "\"baz-alias\" : {}");
createIndex("squash", Settings.EMPTY);
assertBusy(() -> {
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices("foo", "baz");
GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices("foo-01", "baz-01");
GetSettingsResponse settingsResponse = highLevelClient().indices().getSettings(getSettingsRequest, RequestOptions.DEFAULT);
assertThat(settingsResponse.getSetting("foo", "index.lifecycle.name"), equalTo(policy.getName()));
assertThat(settingsResponse.getSetting("baz", "index.lifecycle.name"), equalTo(policy.getName()));
assertThat(settingsResponse.getSetting("foo", "index.lifecycle.phase"), equalTo("hot"));
assertThat(settingsResponse.getSetting("baz", "index.lifecycle.phase"), equalTo("hot"));
assertThat(settingsResponse.getSetting("foo-01", "index.lifecycle.name"), equalTo(policy.getName()));
assertThat(settingsResponse.getSetting("baz-01", "index.lifecycle.name"), equalTo(policy.getName()));
assertThat(settingsResponse.getSetting("foo-01", "index.lifecycle.phase"), equalTo("hot"));
assertThat(settingsResponse.getSetting("baz-01", "index.lifecycle.phase"), equalTo("hot"));
});
ExplainLifecycleRequest req = new ExplainLifecycleRequest();
req.indices("foo", "baz", "squash");
req.indices("foo-01", "baz-01", "squash");
ExplainLifecycleResponse response = execute(req, highLevelClient().indexLifecycle()::explainLifecycle,
highLevelClient().indexLifecycle()::explainLifecycleAsync);
Map<String, IndexLifecycleExplainResponse> indexResponses = response.getIndexResponses();
assertEquals(3, indexResponses.size());
IndexLifecycleExplainResponse fooResponse = indexResponses.get("foo");
IndexLifecycleExplainResponse fooResponse = indexResponses.get("foo-01");
assertNotNull(fooResponse);
assertTrue(fooResponse.managedByILM());
assertEquals("foo", fooResponse.getIndex());
assertEquals("foo-01", fooResponse.getIndex());
assertEquals("hot", fooResponse.getPhase());
assertEquals("rollover", fooResponse.getAction());
assertEquals("attempt_rollover", fooResponse.getStep());
IndexLifecycleExplainResponse bazResponse = indexResponses.get("baz");
IndexLifecycleExplainResponse bazResponse = indexResponses.get("baz-01");
assertNotNull(bazResponse);
assertTrue(bazResponse.managedByILM());
assertEquals("baz", bazResponse.getIndex());
assertEquals("baz-01", bazResponse.getIndex());
assertEquals("hot", bazResponse.getPhase());
assertEquals("rollover", bazResponse.getAction());
assertEquals("attempt_rollover", bazResponse.getStep());

View File

@ -543,6 +543,14 @@ public abstract class ESRestTestCase extends ESTestCase {
client().performRequest(request);
}
protected static void createIndex(String name, Settings settings, String mapping, String aliases) throws IOException {
Request request = new Request("PUT", "/" + name);
request.setJsonEntity("{\n \"settings\": " + Strings.toString(settings)
+ ", \"mappings\" : {" + mapping + "}"
+ ", \"aliases\": {" + aliases + "} }");
client().performRequest(request);
}
protected static void deleteIndex(String name) throws IOException {
Request request = new Request("DELETE", "/" + name);
client().performRequest(request);

View File

@ -28,7 +28,6 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;
/**
@ -165,10 +164,9 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
*
* @param client The Elasticsearch Client to use during execution of {@link AsyncActionStep}
* and {@link AsyncWaitStep} steps.
* @param nowSupplier The supplier of the current time for {@link PhaseAfterStep} steps.
* @return The list of {@link Step} objects in order of their execution.
*/
public List<Step> toSteps(Client client, LongSupplier nowSupplier) {
public List<Step> toSteps(Client client) {
List<Step> steps = new ArrayList<>();
List<Phase> orderedPhases = type.getOrderedPhases(phases);
ListIterator<Phase> phaseIterator = orderedPhases.listIterator(orderedPhases.size());
@ -187,8 +185,8 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
if (phase != null) {
// after step should have the name of the previous phase since the index is still in the
// previous phase until the after condition is reached
Step.StepKey afterStepKey = new Step.StepKey(previousPhase.getName(), PhaseAfterStep.NAME, PhaseAfterStep.NAME);
Step phaseAfterStep = new PhaseAfterStep(nowSupplier, phase.getAfter(), afterStepKey, lastStepKey);
Step.StepKey afterStepKey = new Step.StepKey(previousPhase.getName(), PhaseCompleteStep.NAME, PhaseCompleteStep.NAME);
Step phaseAfterStep = new PhaseCompleteStep(afterStepKey, lastStepKey);
steps.add(phaseAfterStep);
lastStepKey = phaseAfterStep.getKey();
}
@ -211,8 +209,8 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
if (phase != null) {
// The very first after step is in a phase before the hot phase so call this "new"
Step.StepKey afterStepKey = new Step.StepKey("new", PhaseAfterStep.NAME, PhaseAfterStep.NAME);
Step phaseAfterStep = new PhaseAfterStep(nowSupplier, phase.getAfter(), afterStepKey, lastStepKey);
Step.StepKey afterStepKey = new Step.StepKey("new", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME);
Step phaseAfterStep = new PhaseCompleteStep(afterStepKey, lastStepKey);
steps.add(phaseAfterStep);
lastStepKey = phaseAfterStep.getKey();
}
@ -289,7 +287,7 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
// there are no more steps we should execute
return TerminalPolicyStep.KEY;
} else {
return new StepKey(currentPhaseName, PhaseAfterStep.NAME, PhaseAfterStep.NAME);
return new StepKey(currentPhaseName, PhaseCompleteStep.NAME, PhaseCompleteStep.NAME);
}
}
@ -306,7 +304,7 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy>
// InitializePolicyContextStep
return InitializePolicyContextStep.KEY;
}
return new StepKey(prevPhaseName, PhaseAfterStep.NAME, PhaseAfterStep.NAME);
return new StepKey(prevPhaseName, PhaseCompleteStep.NAME, PhaseCompleteStep.NAME);
}
}

View File

@ -1,60 +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;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.Index;
import java.util.Objects;
import java.util.function.LongSupplier;
public class PhaseAfterStep extends ClusterStateWaitStep {
public static final String NAME = "after";
private final TimeValue after;
private final LongSupplier nowSupplier;
PhaseAfterStep(LongSupplier nowSupplier, TimeValue after, StepKey key, StepKey nextStepKey) {
super(key, nextStepKey);
this.nowSupplier = nowSupplier;
this.after = after;
}
@Override
public Result isConditionMet(Index index, ClusterState clusterState) {
IndexMetaData indexMetaData = clusterState.metaData().index(index);
long lifecycleDate = indexMetaData.getSettings()
.getAsLong(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE, -1L);
return new Result(nowSupplier.getAsLong() >= lifecycleDate + after.getMillis(), null);
}
TimeValue getAfter() {
return after;
}
LongSupplier getNowSupplier() {
return nowSupplier;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), after);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PhaseAfterStep other = (PhaseAfterStep) obj;
return super.equals(obj) &&
Objects.equals(after, other.after);
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle;
/**
* This is essentially a marker that a phase has ended, and we need to check
* the age of an index before proceeding to the next phase.
*/
public class PhaseCompleteStep extends Step {
public static final String NAME = "complete";
public PhaseCompleteStep(StepKey key, StepKey nextStepKey) {
super(key, nextStepKey);
}
}

View File

@ -30,7 +30,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.equalTo;
@ -170,11 +169,10 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
public void testFirstAndLastSteps() {
Client client = mock(Client.class);
LongSupplier nowSupplier = () -> 0L;
lifecycleName = randomAlphaOfLengthBetween(1, 20);
Map<String, Phase> phases = new LinkedHashMap<>();
LifecyclePolicy policy = new LifecyclePolicy(TestLifecycleType.INSTANCE, lifecycleName, phases);
List<Step> steps = policy.toSteps(client, nowSupplier);
List<Step> steps = policy.toSteps(client);
assertThat(steps.size(), equalTo(2));
assertThat(steps.get(0), instanceOf(InitializePolicyContextStep.class));
assertThat(steps.get(0).getKey(), equalTo(new StepKey("new", "init", "init")));
@ -184,7 +182,6 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
public void testToStepsWithOneStep() {
Client client = mock(Client.class);
LongSupplier nowSupplier = () -> 0L;
MockStep mockStep = new MockStep(
new Step.StepKey("test", "test", "test"), TerminalPolicyStep.KEY);
@ -196,8 +193,8 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
phases.put(firstPhase.getName(), firstPhase);
LifecyclePolicy policy = new LifecyclePolicy(TestLifecycleType.INSTANCE, lifecycleName, phases);
StepKey firstStepKey = InitializePolicyContextStep.KEY;
StepKey secondStepKey = new StepKey("new", PhaseAfterStep.NAME, PhaseAfterStep.NAME);
List<Step> steps = policy.toSteps(client, nowSupplier);
StepKey secondStepKey = new StepKey("new", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME);
List<Step> steps = policy.toSteps(client);
assertThat(steps.size(), equalTo(4));
assertSame(steps.get(0).getKey(), firstStepKey);
assertThat(steps.get(0).getNextStepKey(), equalTo(secondStepKey));
@ -210,13 +207,12 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
public void testToStepsWithTwoPhases() {
Client client = mock(Client.class);
LongSupplier nowSupplier = () -> 0L;
MockStep secondActionStep = new MockStep(new StepKey("second_phase", "test2", "test"), TerminalPolicyStep.KEY);
MockStep secondAfter = new MockStep(new StepKey("first_phase", PhaseAfterStep.NAME, PhaseAfterStep.NAME),
MockStep secondAfter = new MockStep(new StepKey("first_phase", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME),
secondActionStep.getKey());
MockStep firstActionAnotherStep = new MockStep(new StepKey("first_phase", "test", "bar"), secondAfter.getKey());
MockStep firstActionStep = new MockStep(new StepKey("first_phase", "test", "foo"), firstActionAnotherStep.getKey());
MockStep firstAfter = new MockStep(new StepKey("new", PhaseAfterStep.NAME, PhaseAfterStep.NAME), firstActionStep.getKey());
MockStep firstAfter = new MockStep(new StepKey("new", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME), firstActionStep.getKey());
MockStep init = new MockStep(InitializePolicyContextStep.KEY, firstAfter.getKey());
lifecycleName = randomAlphaOfLengthBetween(1, 20);
@ -231,17 +227,17 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
phases.put(secondPhase.getName(), secondPhase);
LifecyclePolicy policy = new LifecyclePolicy(TestLifecycleType.INSTANCE, lifecycleName, phases);
List<Step> steps = policy.toSteps(client, nowSupplier);
List<Step> steps = policy.toSteps(client);
assertThat(steps.size(), equalTo(7));
assertThat(steps.get(0).getClass(), equalTo(InitializePolicyContextStep.class));
assertThat(steps.get(0).getKey(), equalTo(init.getKey()));
assertThat(steps.get(0).getNextStepKey(), equalTo(init.getNextStepKey()));
assertThat(steps.get(1).getClass(), equalTo(PhaseAfterStep.class));
assertThat(steps.get(1).getClass(), equalTo(PhaseCompleteStep.class));
assertThat(steps.get(1).getKey(), equalTo(firstAfter.getKey()));
assertThat(steps.get(1).getNextStepKey(), equalTo(firstAfter.getNextStepKey()));
assertThat(steps.get(2), equalTo(firstActionStep));
assertThat(steps.get(3), equalTo(firstActionAnotherStep));
assertThat(steps.get(4).getClass(), equalTo(PhaseAfterStep.class));
assertThat(steps.get(4).getClass(), equalTo(PhaseCompleteStep.class));
assertThat(steps.get(4).getKey(), equalTo(secondAfter.getKey()));
assertThat(steps.get(4).getNextStepKey(), equalTo(secondAfter.getNextStepKey()));
assertThat(steps.get(5), equalTo(secondActionStep));
@ -337,7 +333,7 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
currentStep = new StepKey("phase_1", "action_3", "step_missing");
nextStep = policy.getNextValidStep(currentStep);
assertNotNull(nextStep);
assertEquals(new StepKey("phase_1", PhaseAfterStep.NAME, PhaseAfterStep.NAME), nextStep);
assertEquals(new StepKey("phase_1", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME), nextStep);
// current action exists but step does not and action is last in the
// last phase
@ -356,7 +352,7 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
currentStep = new StepKey("phase_1", "action_4", "step_2");
nextStep = policy.getNextValidStep(currentStep);
assertNotNull(nextStep);
assertEquals(new StepKey("phase_1", PhaseAfterStep.NAME, PhaseAfterStep.NAME), nextStep);
assertEquals(new StepKey("phase_1", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME), nextStep);
// current action no longer exists and action was last in the last phase
currentStep = new StepKey("phase_4", "action_4", "step_2");
@ -368,7 +364,7 @@ public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecycleP
currentStep = new StepKey("phase_3", "action_2", "step_2");
nextStep = policy.getNextValidStep(currentStep);
assertNotNull(nextStep);
assertEquals(new StepKey("phase_2", PhaseAfterStep.NAME, PhaseAfterStep.NAME), nextStep);
assertEquals(new StepKey("phase_2", PhaseCompleteStep.NAME, PhaseCompleteStep.NAME), nextStep);
// current phase no longer exists and was last phase
currentStep = new StepKey("phase_5", "action_2", "step_2");

View File

@ -1,103 +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;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateWaitStep.Result;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
import java.util.concurrent.TimeUnit;
public class PhaseAfterStepTests extends AbstractStepTestCase<PhaseAfterStep> {
@Override
public PhaseAfterStep createRandomInstance() {
StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
TimeValue after = createRandomTimeValue();
return new PhaseAfterStep(null, after, stepKey, nextStepKey);
}
private TimeValue createRandomTimeValue() {
return new TimeValue(randomLongBetween(1, 10000), randomFrom(TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS, TimeUnit.DAYS));
}
@Override
public PhaseAfterStep mutateInstance(PhaseAfterStep instance) {
StepKey key = instance.getKey();
StepKey nextKey = instance.getNextStepKey();
TimeValue after = instance.getAfter();
switch (between(0, 2)) {
case 0:
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
break;
case 1:
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
break;
case 2:
after = randomValueOtherThan(after, this::createRandomTimeValue);
break;
default:
throw new AssertionError("Illegal randomisation branch");
}
return new PhaseAfterStep(instance.getNowSupplier(), after, key, nextKey);
}
@Override
public PhaseAfterStep copyInstance(PhaseAfterStep instance) {
return new PhaseAfterStep(instance.getNowSupplier(), instance.getAfter(),
instance.getKey(), instance.getNextStepKey());
}
public void testConditionMet() {
long creationDate = randomNonNegativeLong();
IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLength(5))
.settings(settings(Version.CURRENT).put(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE, creationDate))
.creationDate(creationDate)
.numberOfShards(1).numberOfReplicas(0).build();
MetaData metaData = MetaData.builder()
.persistentSettings(settings(Version.CURRENT).build())
.put(IndexMetaData.builder(indexMetadata))
.build();
Index index = indexMetadata.getIndex();
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
long after = randomNonNegativeLong();
long now = creationDate + after + randomIntBetween(0, 2);
PhaseAfterStep step = new PhaseAfterStep(() -> now, TimeValue.timeValueMillis(after), null, null);
Result result = step.isConditionMet(index, clusterState);
assertTrue(result.isComplete());
assertNull(result.getInfomationContext());
}
public void testConditionNotMet() {
long creationDate = randomNonNegativeLong();
IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLength(5))
.settings(settings(Version.CURRENT).put(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE, creationDate))
.creationDate(creationDate)
.numberOfShards(1).numberOfReplicas(0).build();
MetaData metaData = MetaData.builder()
.persistentSettings(settings(Version.CURRENT).build())
.put(IndexMetaData.builder(indexMetadata))
.build();
Index index = indexMetadata.getIndex();
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
long after = randomNonNegativeLong();
long now = creationDate + after - randomIntBetween(1, 1000);
PhaseAfterStep step = new PhaseAfterStep(() -> now, TimeValue.timeValueMillis(after), null, null);
Result result = step.isConditionMet(index, clusterState);
assertFalse(result.isComplete());
assertNull(result.getInfomationContext());
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
public class PhaseCompleteStepTests extends AbstractStepTestCase<PhaseCompleteStep> {
@Override
public PhaseCompleteStep createRandomInstance() {
StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
return new PhaseCompleteStep(stepKey, nextStepKey);
}
@Override
public PhaseCompleteStep mutateInstance(PhaseCompleteStep instance) {
StepKey key = instance.getKey();
StepKey nextKey = instance.getNextStepKey();
if (randomBoolean()) {
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
} else {
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
}
return new PhaseCompleteStep(key, nextKey);
}
@Override
public PhaseCompleteStep copyInstance(PhaseCompleteStep instance) {
return new PhaseCompleteStep(instance.getKey(), instance.getNextStepKey());
}
}

View File

@ -16,6 +16,7 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -30,6 +31,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
import org.elasticsearch.xpack.core.indexlifecycle.PhaseCompleteStep;
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
import org.elasticsearch.xpack.core.indexlifecycle.Step;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
@ -51,6 +53,31 @@ public class IndexLifecycleRunner {
this.nowSupplier = nowSupplier;
}
/**
* Return true or false depending on whether the index is ready to be in {@code phase}
*/
boolean isReadyToTransitionToThisPhase(final String policy, final IndexMetaData indexMetaData, final String phase) {
final Settings indexSettings = indexMetaData.getSettings();
if (indexSettings.hasValue(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE) == false) {
logger.trace("no index creation date has been set yet");
return true;
}
final long lifecycleDate = indexSettings.getAsLong(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE, -1L);
assert lifecycleDate >= 0 : "expected index to have a lifecycle date but it did not";
final TimeValue after = stepRegistry.getIndexAgeForPhase(policy, phase);
final long now = nowSupplier.getAsLong();
final TimeValue age = new TimeValue(now - lifecycleDate);
if (logger.isTraceEnabled()) {
logger.trace("[{}] checking for index age to be at least [{}] before performing actions in " +
"the \"{}\" phase. Now: {}, lifecycle date: {}, age: [{}/{}s]",
indexMetaData.getIndex().getName(), after, phase,
new TimeValue(now).seconds(),
new TimeValue(lifecycleDate).seconds(),
age, age.seconds());
}
return now >= lifecycleDate + after.getMillis();
}
public void runPolicy(String policy, IndexMetaData indexMetaData, ClusterState currentState,
boolean fromClusterStateChange) {
Settings indexSettings = indexMetaData.getSettings();
@ -67,13 +94,23 @@ public class IndexLifecycleRunner {
+ "] with policy [" + policy + "] is not recognized");
return;
}
logger.debug("running policy with current-step[" + currentStep.getKey() + "]");
logger.debug("running policy with current-step [" + currentStep.getKey() + "]");
if (currentStep instanceof TerminalPolicyStep) {
logger.debug("policy [" + policy + "] for index [" + indexMetaData.getIndex().getName() + "] complete, skipping execution");
return;
} else if (currentStep instanceof ErrorStep) {
logger.debug(
"policy [" + policy + "] for index [" + indexMetaData.getIndex().getName() + "] on an error step, skipping execution");
} else if (currentStep instanceof ClusterStateActionStep || currentStep instanceof ClusterStateWaitStep) {
"policy [" + policy + "] for index [" + indexMetaData.getIndex().getName() + "] on an error step, skipping execution");
return;
} else if (currentStep instanceof PhaseCompleteStep) {
// Only proceed to the next step if enough time has elapsed to go into the next phase
if (isReadyToTransitionToThisPhase(policy, indexMetaData, currentStep.getNextStepKey().getPhase())) {
moveToStep(indexMetaData.getIndex(), policy, currentStep.getKey(), currentStep.getNextStepKey());
}
return;
}
if (currentStep instanceof ClusterStateActionStep || currentStep instanceof ClusterStateWaitStep) {
executeClusterStateSteps(indexMetaData.getIndex(), policy, currentStep);
} else if (currentStep instanceof AsyncWaitStep) {
if (fromClusterStateChange == false) {

View File

@ -146,7 +146,7 @@ public class IndexLifecycleService extends AbstractComponent
policyRegistry.removeIndices(event.indicesDeleted());
}
if (event.state().metaData().custom(IndexLifecycleMetadata.TYPE) != null) {
policyRegistry.update(event.state(), client, nowSupplier);
policyRegistry.update(event.state(), client);
}
}
}

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.indexlifecycle;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateUpdateTask;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
@ -51,7 +52,12 @@ public class MoveToNextStepUpdateTask extends ClusterStateUpdateTask {
@Override
public ClusterState execute(ClusterState currentState) {
Settings indexSettings = currentState.getMetaData().index(index).getSettings();
IndexMetaData indexMetaData = currentState.getMetaData().index(index);
if (indexMetaData == null) {
// Index must have been since deleted, ignore it
return currentState;
}
Settings indexSettings = indexMetaData.getSettings();
if (policy.equals(LifecycleSettings.LIFECYCLE_NAME_SETTING.get(indexSettings))
&& currentStepKey.equals(IndexLifecycleRunner.getCurrentStepKey(indexSettings))) {
return IndexLifecycleRunner.moveClusterStateToNextStep(index, currentState, currentStepKey, nextStepKey, nowSupplier);

View File

@ -16,6 +16,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
@ -39,7 +40,6 @@ import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.LongSupplier;
import java.util.stream.Collectors;
public class PolicyStepsRegistry {
@ -97,7 +97,7 @@ public class PolicyStepsRegistry {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void update(ClusterState clusterState, Client client, LongSupplier nowSupplier) {
public void update(ClusterState clusterState, Client client) {
final IndexLifecycleMetadata meta = clusterState.metaData().custom(IndexLifecycleMetadata.TYPE);
assert meta != null : "IndexLifecycleMetadata cannot be null when updating the policy steps registry";
@ -134,7 +134,7 @@ public class PolicyStepsRegistry {
LifecyclePolicySecurityClient policyClient = new LifecyclePolicySecurityClient(client, ClientHelper.INDEX_LIFECYCLE_ORIGIN,
policyMetadata.getHeaders());
lifecyclePolicyMap.put(policyMetadata.getName(), policyMetadata);
List<Step> policyAsSteps = policyMetadata.getPolicy().toSteps(policyClient, nowSupplier);
List<Step> policyAsSteps = policyMetadata.getPolicy().toSteps(policyClient);
if (policyAsSteps.isEmpty() == false) {
firstStepMap.put(policyMetadata.getName(), policyAsSteps.get(0));
final Map<Step.StepKey, Step> stepMapForPolicy = new HashMap<>();
@ -192,7 +192,7 @@ public class PolicyStepsRegistry {
}
LifecyclePolicySecurityClient policyClient = new LifecyclePolicySecurityClient(client,
ClientHelper.INDEX_LIFECYCLE_ORIGIN, lifecyclePolicyMap.get(policy).getHeaders());
final List<Step> steps = policyToExecute.toSteps(policyClient, nowSupplier);
final List<Step> steps = policyToExecute.toSteps(policyClient);
// Build a list of steps that correspond with the phase the index is currently in
final List<Step> phaseSteps;
if (steps == null) {
@ -257,4 +257,22 @@ public class PolicyStepsRegistry {
return firstStepMap.get(policy);
}
public TimeValue getIndexAgeForPhase(final String policy, final String phase) {
// These built in phases should never wait
if (InitializePolicyContextStep.INITIALIZATION_PHASE.equals(phase) || TerminalPolicyStep.COMPLETED_PHASE.equals(phase)) {
return TimeValue.ZERO;
}
final LifecyclePolicyMetadata meta = lifecyclePolicyMap.get(policy);
if (meta == null) {
throw new IllegalArgumentException("no policy found with name \"" + policy + "\"");
} else {
final Phase retrievedPhase = meta.getPolicy().getPhases().get(phase);
if (retrievedPhase == null) {
// We don't have that phase registered, proceed right through it
return TimeValue.ZERO;
} else {
return retrievedPhase.getAfter();
}
}
}
}

View File

@ -15,15 +15,12 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.index.Index;
import org.elasticsearch.node.Node;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
@ -31,6 +28,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyMetadata;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
import org.elasticsearch.xpack.core.indexlifecycle.MockAction;
import org.elasticsearch.xpack.core.indexlifecycle.MockStep;
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
import org.elasticsearch.xpack.core.indexlifecycle.Step;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
@ -129,44 +127,7 @@ public class ExecuteStepsUpdateTaskTests extends ESTestCase {
.metaData(metaData)
.nodes(DiscoveryNodes.builder().localNodeId(nodeId).masterNodeId(nodeId).add(masterNode).build())
.build();
policyStepsRegistry.update(clusterState, client, () -> 0L);
}
public void testExecuteAllUntilEndOfPhase() throws IOException {
NamedXContentRegistry registry = new NamedXContentRegistry(
Collections.singletonList(new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(MockAction.NAME),
(p) -> {
MockAction.parse(p);
return new MockAction(Arrays.asList(firstStep, allClusterSecondStep));
})));
policyStepsRegistry = new PolicyStepsRegistry(registry);
setupIndexPolicy(allClusterPolicyName);
Step startStep = policyStepsRegistry.getFirstStep(allClusterPolicyName);
long now = randomNonNegativeLong();
// test execute start till end of phase `new`
ExecuteStepsUpdateTask task = new ExecuteStepsUpdateTask(allClusterPolicyName, index, startStep, policyStepsRegistry, () -> now);
ClusterState newState = task.execute(clusterState);
// Update the registry so the next phase's steps are loaded
policyStepsRegistry.update(newState, client, () -> now);
// verify that both the `new` phase was executed and the next phase is to begin
StepKey currentStepKey = IndexLifecycleRunner.getCurrentStepKey(newState.metaData().index(index).getSettings());
assertThat(currentStepKey, equalTo(firstStep.getKey()));
// test execute all actions in same phase
task = new ExecuteStepsUpdateTask(allClusterPolicyName, index, firstStep, policyStepsRegistry, () -> now);
newState = task.execute(newState);
policyStepsRegistry.update(newState, client, () -> now);
assertThat(firstStep.getExecuteCount(), equalTo(1L));
assertThat(allClusterSecondStep.getExecuteCount(), equalTo(1L));
currentStepKey = IndexLifecycleRunner.getCurrentStepKey(newState.metaData().index(index).getSettings());
assertThat(currentStepKey, equalTo(TerminalPolicyStep.KEY));
assertNull(policyStepsRegistry.getStep(index, currentStepKey).getNextStepKey());
assertThat(LifecycleSettings.LIFECYCLE_PHASE_TIME_SETTING.get(newState.metaData().index(index).getSettings()), equalTo(now));
assertThat(LifecycleSettings.LIFECYCLE_ACTION_TIME_SETTING.get(newState.metaData().index(index).getSettings()), equalTo(now));
assertThat(LifecycleSettings.LIFECYCLE_STEP_INFO_SETTING.get(newState.metaData().index(index).getSettings()), equalTo(""));
policyStepsRegistry.update(clusterState, client);
}
public void testNeverExecuteNonClusterStateStep() throws IOException {
@ -201,7 +162,7 @@ public class ExecuteStepsUpdateTaskTests extends ESTestCase {
.put(LifecycleSettings.LIFECYCLE_PHASE, (String) null)
.put(LifecycleSettings.LIFECYCLE_ACTION, (String) null)
.put(LifecycleSettings.LIFECYCLE_STEP, (String) null).build()))).build();
policyStepsRegistry.update(clusterState, client, () -> 0);
policyStepsRegistry.update(clusterState, client);
Step invalidStep = new MockClusterStateActionStep(firstStepKey, secondStepKey);
long now = randomNonNegativeLong();
@ -266,6 +227,6 @@ public class ExecuteStepsUpdateTaskTests extends ESTestCase {
.put(LifecycleSettings.LIFECYCLE_PHASE, stepKey.getPhase())
.put(LifecycleSettings.LIFECYCLE_ACTION, stepKey.getAction())
.put(LifecycleSettings.LIFECYCLE_STEP, stepKey.getName()).build()))).build();
policyStepsRegistry.update(clusterState, client, () -> 0);
policyStepsRegistry.update(clusterState, client);
}
}

View File

@ -22,8 +22,6 @@ import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyTests;
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.AbstractStepTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.AsyncActionStep;
@ -35,9 +33,11 @@ import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyMetadata;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyTests;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
import org.elasticsearch.xpack.core.indexlifecycle.MockAction;
import org.elasticsearch.xpack.core.indexlifecycle.MockStep;
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
import org.elasticsearch.xpack.core.indexlifecycle.Step;
@ -54,6 +54,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -1058,6 +1060,47 @@ public class IndexLifecycleRunnerTests extends ESTestCase {
assertIndexNotManagedByILM(newClusterState, index);
}
public void testIsReadyToTransition() {
String policyName = "async_action_policy";
StepKey stepKey = new StepKey("phase", MockAction.NAME, MockAction.NAME);
MockAsyncActionStep step = new MockAsyncActionStep(stepKey, null);
step.setWillComplete(true);
SortedMap<String, LifecyclePolicyMetadata> lifecyclePolicyMap = new TreeMap<>(Collections.singletonMap(policyName,
new LifecyclePolicyMetadata(createPolicy(policyName, null, step.getKey()), new HashMap<>())));
Index index = new Index("my_index", "uuid");
Map<String, Step> firstStepMap = Collections.singletonMap(policyName, step);
Map<StepKey, Step> policySteps = Collections.singletonMap(step.getKey(), step);
Map<String, Map<StepKey, Step>> stepMap = Collections.singletonMap(policyName, policySteps);
Map<Index, List<Step>> indexSteps = Collections.singletonMap(index, Collections.singletonList(step));
PolicyStepsRegistry policyStepsRegistry = new PolicyStepsRegistry(lifecyclePolicyMap, firstStepMap,
stepMap, indexSteps, NamedXContentRegistry.EMPTY);
ClusterService clusterService = mock(ClusterService.class);
final AtomicLong now = new AtomicLong(5);
IndexLifecycleRunner runner = new IndexLifecycleRunner(policyStepsRegistry, clusterService, now::get);
IndexMetaData indexMetaData = IndexMetaData.builder("my_index").settings(settings(Version.CURRENT))
.numberOfShards(randomIntBetween(1, 5))
.numberOfReplicas(randomIntBetween(0, 5))
.build();
// With no time, always transition
assertTrue("index should be able to transition with no creation date",
runner.isReadyToTransitionToThisPhase(policyName, indexMetaData, "phase"));
indexMetaData = IndexMetaData.builder(indexMetaData)
.settings(Settings.builder()
.put(indexMetaData.getSettings())
.put(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE, 10L)
.build())
.build();
// Index is not old enough to transition
assertFalse("index is not able to transition if it isn't old enough",
runner.isReadyToTransitionToThisPhase(policyName, indexMetaData, "phase"));
// Set to the fuuuuuttuuuuuuurre
now.set(Long.MAX_VALUE);
assertTrue("index should be able to transition past phase's age",
runner.isReadyToTransitionToThisPhase(policyName, indexMetaData, "phase"));
}
public static void assertIndexNotManagedByILM(ClusterState clusterState, Index index) {
MetaData metadata = clusterState.metaData();
assertNotNull(metadata);

View File

@ -59,7 +59,7 @@ public class MoveToNextStepUpdateTaskTests extends ESTestCase {
public void testExecuteSuccessfullyMoved() {
long now = randomNonNegativeLong();
List<Step> steps = lifecyclePolicy.toSteps(null, () -> now);
List<Step> steps = lifecyclePolicy.toSteps(null);
StepKey currentStepKey = steps.get(0).getKey();
StepKey nextStepKey = steps.get(0).getNextStepKey();
@ -103,7 +103,7 @@ public class MoveToNextStepUpdateTaskTests extends ESTestCase {
public void testExecuteSuccessfulMoveWithInvalidNextStep() {
long now = randomNonNegativeLong();
List<Step> steps = lifecyclePolicy.toSteps(null, () -> now);
List<Step> steps = lifecyclePolicy.toSteps(null);
StepKey currentStepKey = steps.get(0).getKey();
StepKey invalidNextStep = new StepKey("next-invalid", "next-invalid", "next-invalid");

View File

@ -109,7 +109,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
String policyName = randomAlphaOfLength(5);
LifecyclePolicy newPolicy = LifecyclePolicyTests.randomTestLifecyclePolicy(policyName);
logger.info("--> policy: {}", newPolicy);
List<Step> policySteps = newPolicy.toSteps(client, () -> 0L);
List<Step> policySteps = newPolicy.toSteps(client);
Map<String, String> headers = new HashMap<>();
if (randomBoolean()) {
headers.put(randomAlphaOfLength(10), randomAlphaOfLength(10));
@ -149,7 +149,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
PolicyStepsRegistry registry = new PolicyStepsRegistry(NamedXContentRegistry.EMPTY);
// add new policy
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
assertThat(registry.getFirstStep(newPolicy.getName()), equalTo(policySteps.get(0)));
assertThat(registry.getLifecyclePolicyMap().size(), equalTo(1));
@ -167,7 +167,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
.put(LifecycleSettings.LIFECYCLE_PHASE, step.getKey().getPhase()))))
.nodes(DiscoveryNodes.builder().localNodeId(nodeId).masterNodeId(nodeId).add(masterNode).build())
.build();
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
assertThat(registeredStepsForPolicy.get(step.getKey()), equalTo(step));
assertThat(registry.getStep(index, step.getKey()), equalTo(step));
}
@ -175,7 +175,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
Map<String, LifecyclePolicyMetadata> registryPolicyMap = registry.getLifecyclePolicyMap();
Map<String, Step> registryFirstStepMap = registry.getFirstStepMap();
Map<String, Map<Step.StepKey, Step>> registryStepMap = registry.getStepMap();
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
assertThat(registry.getLifecyclePolicyMap(), equalTo(registryPolicyMap));
assertThat(registry.getFirstStepMap(), equalTo(registryFirstStepMap));
assertThat(registry.getStepMap(), equalTo(registryStepMap));
@ -186,7 +186,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
.metaData(
MetaData.builder(metaData)
.putCustom(IndexLifecycleMetadata.TYPE, lifecycleMetadata)).build();
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
assertTrue(registry.getLifecyclePolicyMap().isEmpty());
assertTrue(registry.getFirstStepMap().isEmpty());
assertTrue(registry.getStepMap().isEmpty());
@ -219,7 +219,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
.build();
PolicyStepsRegistry registry = new PolicyStepsRegistry(NamedXContentRegistry.EMPTY);
// add new policy
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
// swap out policy
newPolicy = LifecyclePolicyTests.randomTestLifecyclePolicy(policyName);
@ -227,7 +227,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
new LifecyclePolicyMetadata(newPolicy, Collections.emptyMap())), OperationMode.RUNNING);
currentState = ClusterState.builder(currentState)
.metaData(MetaData.builder(metaData).putCustom(IndexLifecycleMetadata.TYPE, lifecycleMetadata)).build();
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
// TODO(talevy): assert changes... right now we do not support updates to policies. will require internal cleanup
}
@ -249,7 +249,7 @@ 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, () -> 0L);
List<Step> policySteps = newPolicy.toSteps(client);
Map<String, String> headers = new HashMap<>();
if (randomBoolean()) {
headers.put(randomAlphaOfLength(10), randomAlphaOfLength(10));
@ -289,7 +289,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
PolicyStepsRegistry registry = new PolicyStepsRegistry(NamedXContentRegistry.EMPTY);
// add new policy
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
Map<Step.StepKey, Step> registeredStepsForPolicy = registry.getStepMap().get(newPolicy.getName());
Step shrinkStep = registeredStepsForPolicy.entrySet().stream()
@ -314,7 +314,7 @@ public class PolicyStepsRegistryTests extends ESTestCase {
currentState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
// Update the policies
registry.update(currentState, client, () -> 0L);
registry.update(currentState, client);
registeredStepsForPolicy = registry.getStepMap().get(newPolicy.getName());
shrinkStep = registeredStepsForPolicy.entrySet().stream()

View File

@ -76,8 +76,8 @@ teardown:
body:
current_step:
phase: "new"
action: "after"
name: "after"
action: "complete"
name: "complete"
next_step:
phase: "warm"
action: "forcemerge"
@ -116,8 +116,8 @@ teardown:
indices.get:
index: my_index
- match: { my_index.settings.index.lifecycle.name: "my_moveable_timeseries_lifecycle" }
- match: { my_index.settings.index.lifecycle.step: "after" }
- match: { my_index.settings.index.lifecycle.action: "after" }
- match: { my_index.settings.index.lifecycle.step: "complete" }
- match: { my_index.settings.index.lifecycle.action: "complete" }
- match: { my_index.settings.index.lifecycle.phase: "new" }
---
@ -130,8 +130,8 @@ teardown:
body:
current_step:
phase: "new"
action: "after"
name: "after"
action: "complete"
name: "complete"
next_step:
phase: "invalid"
action: "invalid"
@ -144,8 +144,8 @@ teardown:
indices.get:
index: my_index
- match: { my_index.settings.index.lifecycle.name: "my_moveable_timeseries_lifecycle" }
- match: { my_index.settings.index.lifecycle.step: "after" }
- match: { my_index.settings.index.lifecycle.action: "after" }
- match: { my_index.settings.index.lifecycle.step: "complete" }
- match: { my_index.settings.index.lifecycle.action: "complete" }
- match: { my_index.settings.index.lifecycle.phase: "new" }
---

View File

@ -73,8 +73,8 @@ teardown:
indices.get:
index: my_index
- match: { my_index.settings.index.lifecycle.name: "my_lifecycle" }
- match: { my_index.settings.index.lifecycle.step: "after" }
- match: { my_index.settings.index.lifecycle.action: "after" }
- match: { my_index.settings.index.lifecycle.step: "complete" }
- match: { my_index.settings.index.lifecycle.action: "complete" }
- match: { my_index.settings.index.lifecycle.phase: "new" }

View File

@ -110,8 +110,8 @@ teardown:
- match: { indices.my_index.index: "my_index" }
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.phase: "new" }
- match: { indices.my_index.action: "after" }
- match: { indices.my_index.step: "after" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.step: "complete" }
- is_false: indices.my_index.failed_step
- is_false: indices.my_index.step_info
@ -131,8 +131,8 @@ teardown:
- match: { indices.my_index.index: "my_index" }
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.phase: "new" }
- match: { indices.my_index.action: "after" }
- match: { indices.my_index.step: "after" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.step: "complete" }
- is_false: indices.my_index.failed_step
- is_false: indices.my_index.step_info
@ -140,8 +140,8 @@ teardown:
- match: { indices.my_index2.index: "my_index2" }
- match: { indices.my_index2.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index2.phase: "new" }
- match: { indices.my_index2.action: "after" }
- match: { indices.my_index2.step: "after" }
- match: { indices.my_index2.action: "complete" }
- match: { indices.my_index2.step: "complete" }
- is_false: indices.my_index2.failed_step
- is_false: indices.my_index2.step_info
@ -161,8 +161,8 @@ teardown:
- match: { indices.my_index.index: "my_index" }
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.phase: "new" }
- match: { indices.my_index.action: "after" }
- match: { indices.my_index.step: "after" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.step: "complete" }
- is_false: indices.my_index.failed_step
- is_false: indices.my_index.step_info
@ -170,8 +170,8 @@ teardown:
- match: { indices.my_index2.index: "my_index2" }
- match: { indices.my_index2.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index2.phase: "new" }
- match: { indices.my_index2.action: "after" }
- match: { indices.my_index2.step: "after" }
- match: { indices.my_index2.action: "complete" }
- match: { indices.my_index2.step: "complete" }
- is_false: indices.my_index2.failed_step
- is_false: indices.my_index2.step_info
@ -179,8 +179,8 @@ teardown:
- match: { indices.another_index.index: "another_index" }
- match: { indices.another_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.another_index.phase: "new" }
- match: { indices.another_index.action: "after" }
- match: { indices.another_index.step: "after" }
- match: { indices.another_index.action: "complete" }
- match: { indices.another_index.step: "complete" }
- is_false: indices.another_index.failed_step
- is_false: indices.another_index.step_info