Skip to content

inherit [index.lifecycle.date] from rolled-over time #30853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jun 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;

import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.index.Index;

public abstract class ClusterStateActionStep extends Step {

public ClusterStateActionStep(StepKey key, StepKey nextStepKey) {
super(key, nextStepKey);
}

public abstract ClusterState performAction(Index index, ClusterState clusterState);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;

public class InitializePolicyContextStep extends Step {
public final class InitializePolicyContextStep extends ClusterStateActionStep {
public static final StepKey KEY = new StepKey("pre-phase", "pre-action", "init");

public InitializePolicyContextStep(Step.StepKey key, StepKey nextStepKey) {
super(key, nextStepKey);
}

@Override
public ClusterState performAction(Index index, ClusterState clusterState) {
Settings settings = clusterState.metaData().index(index).getSettings();
if (settings.hasValue(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;

import java.io.IOException;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

Expand Down Expand Up @@ -104,7 +104,7 @@ public ByteSizeValue getMaxSize() {
public TimeValue getMaxAge() {
return maxAge;
}

public Long getMaxDocs() {
return maxDocs;
}
Expand All @@ -127,8 +127,11 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws

@Override
public List<Step> toSteps(Client client, String phase, Step.StepKey nextStepKey) {
return Collections.singletonList(
new RolloverStep(new StepKey(phase, NAME, RolloverStep.NAME), nextStepKey, client, maxSize, maxAge, maxDocs));
StepKey updateDateStepKey = new StepKey(phase, NAME, UpdateRolloverLifecycleDateStep.NAME);
RolloverStep rolloverStep = new RolloverStep(new StepKey(phase, NAME, RolloverStep.NAME), updateDateStepKey, client,
maxSize, maxAge, maxDocs);
UpdateRolloverLifecycleDateStep updateDateStep = new UpdateRolloverLifecycleDateStep(updateDateStepKey, nextStepKey);
return Arrays.asList(rolloverStep, updateDateStep);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.action.admin.indices.rollover.RolloverInfo;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.Index;

public class UpdateRolloverLifecycleDateStep extends ClusterStateActionStep {
public static final String NAME = "update-rollover-lifecycle-date";

public UpdateRolloverLifecycleDateStep(StepKey key, StepKey nextStepKey) {
super(key, nextStepKey);
}

@Override
public ClusterState performAction(Index index, ClusterState currentState) {
IndexMetaData indexMetaData = currentState.metaData().getIndexSafe(index);
// find the newly created index from the rollover and fetch its index.creation_date
String rolloverAlias = RolloverAction.LIFECYCLE_ROLLOVER_ALIAS_SETTING.get(indexMetaData.getSettings());
if (Strings.isNullOrEmpty(rolloverAlias)) {
throw new IllegalStateException("setting [" + RolloverAction.LIFECYCLE_ROLLOVER_ALIAS
+ "] is not set on index [" + indexMetaData.getIndex().getName() + "]");
}
RolloverInfo rolloverInfo = indexMetaData.getRolloverInfos().get(rolloverAlias);
if (rolloverInfo == null) {
throw new IllegalStateException("index [" + indexMetaData.getIndex().getName() + "] has not rolled over yet");
}
Settings settings = Settings.builder().put(LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE, rolloverInfo.getTime()).build();
return ClusterState.builder(currentState).metaData(MetaData.builder(currentState.metaData())
.updateSettings(settings, indexMetaData.getIndex().getName())).build();
}

@Override
public int hashCode() {
return super.hashCode();
}

@Override
public boolean equals(Object obj) {
return obj != null && getClass() == obj.getClass() && super.equals(obj);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,17 @@ public void testToSteps() {
randomAlphaOfLengthBetween(1, 10));
List<Step> steps = action.toSteps(null, phase, nextStepKey);
assertNotNull(steps);
assertEquals(1, steps.size());
assertEquals(2, steps.size());
StepKey expectedFirstStepKey = new StepKey(phase, RolloverAction.NAME, RolloverStep.NAME);
StepKey expectedSecondStepKey = new StepKey(phase, RolloverAction.NAME, UpdateRolloverLifecycleDateStep.NAME);
RolloverStep firstStep = (RolloverStep) steps.get(0);
UpdateRolloverLifecycleDateStep secondStep = (UpdateRolloverLifecycleDateStep) steps.get(1);
assertEquals(expectedFirstStepKey, firstStep.getKey());
assertEquals(nextStepKey, firstStep.getNextStepKey());
assertEquals(expectedSecondStepKey, secondStep.getKey());
assertEquals(secondStep.getKey(), firstStep.getNextStepKey());
assertEquals(action.getMaxSize(), firstStep.getMaxSize());
assertEquals(action.getMaxAge(), firstStep.getMaxAge());
assertEquals(action.getMaxDocs(), firstStep.getMaxDocs());
assertEquals(nextStepKey, secondStep.getNextStepKey());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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.action.admin.indices.rollover.RolloverInfo;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;

import java.util.Collections;

import static org.hamcrest.Matchers.equalTo;

public class UpdateRolloverLifecycleDateStepTests extends AbstractStepTestCase<UpdateRolloverLifecycleDateStep> {

@Override
public UpdateRolloverLifecycleDateStep createRandomInstance() {
StepKey stepKey = randomStepKey();
StepKey nextStepKey = randomStepKey();
return new UpdateRolloverLifecycleDateStep(stepKey, nextStepKey);
}

@Override
public UpdateRolloverLifecycleDateStep mutateInstance(UpdateRolloverLifecycleDateStep 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 UpdateRolloverLifecycleDateStep(key, nextKey);
}

@Override
public UpdateRolloverLifecycleDateStep copyInstance(UpdateRolloverLifecycleDateStep instance) {
return new UpdateRolloverLifecycleDateStep(instance.getKey(), instance.getNextStepKey());
}

@SuppressWarnings("unchecked")
public void testPerformAction() {
String alias = randomAlphaOfLength(3);
long creationDate = randomLongBetween(0, 1000000);
long rolloverTime = randomValueOtherThan(creationDate, () -> randomNonNegativeLong());
IndexMetaData newIndexMetaData = IndexMetaData.builder(randomAlphaOfLength(11))
.settings(settings(Version.CURRENT)).creationDate(creationDate)
.putAlias(AliasMetaData.builder(alias)).numberOfShards(randomIntBetween(1, 5))
.numberOfReplicas(randomIntBetween(0, 5)).build();
IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10))
.putRolloverInfo(new RolloverInfo(alias, Collections.emptyList(), rolloverTime))
.settings(settings(Version.CURRENT).put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias))
.numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder()
.put(indexMetaData, false)
.put(newIndexMetaData, false)).build();

UpdateRolloverLifecycleDateStep step = createRandomInstance();
ClusterState newState = step.performAction(indexMetaData.getIndex(), clusterState);
long actualRolloverTime = LifecycleSettings.LIFECYCLE_INDEX_CREATION_DATE_SETTING
.get(newState.metaData().index(indexMetaData.getIndex()).getSettings());
assertThat(actualRolloverTime, equalTo(rolloverTime));
}

public void testPerformActionBeforeRolloverHappened() {
String alias = randomAlphaOfLength(3);
long creationDate = randomLongBetween(0, 1000000);
IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(11))
.settings(settings(Version.CURRENT).put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias))
.creationDate(creationDate).putAlias(AliasMetaData.builder(alias)).numberOfShards(randomIntBetween(1, 5))
.numberOfReplicas(randomIntBetween(0, 5)).build();
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData, false)).build();
UpdateRolloverLifecycleDateStep step = createRandomInstance();

IllegalStateException exceptionThrown = expectThrows(IllegalStateException.class,
() -> step.performAction(indexMetaData.getIndex(), clusterState));
assertThat(exceptionThrown.getMessage(),
equalTo("index [" + indexMetaData.getIndex().getName() + "] has not rolled over yet"));
}

public void testPerformActionWithNoRolloverAliasSetting() {
long creationDate = randomLongBetween(0, 1000000);
IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(11))
.settings(settings(Version.CURRENT)).creationDate(creationDate).numberOfShards(randomIntBetween(1, 5))
.numberOfReplicas(randomIntBetween(0, 5)).build();
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT)
.metaData(MetaData.builder().put(indexMetaData, false)).build();
UpdateRolloverLifecycleDateStep step = createRandomInstance();

IllegalStateException exceptionThrown = expectThrows(IllegalStateException.class,
() -> step.performAction(indexMetaData.getIndex(), clusterState));
assertThat(exceptionThrown.getMessage(),
equalTo("setting [index.lifecycle.rollover_alias] is not set on index [" + indexMetaData.getIndex().getName() +"]"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateActionStep;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateWaitStep;
import org.elasticsearch.xpack.core.indexlifecycle.InitializePolicyContextStep;
import org.elasticsearch.xpack.core.indexlifecycle.Step;

import java.io.IOException;
Expand Down Expand Up @@ -58,12 +58,12 @@ public ClusterState execute(ClusterState currentState) throws IOException {
// We can do cluster state steps all together until we
// either get to a step that isn't a cluster state step or a
// cluster state wait step returns not completed
while (currentStep instanceof InitializePolicyContextStep || currentStep instanceof ClusterStateWaitStep) {
if (currentStep instanceof InitializePolicyContextStep) {
while (currentStep instanceof ClusterStateActionStep || currentStep instanceof ClusterStateWaitStep) {
if (currentStep instanceof ClusterStateActionStep) {
// cluster state action step so do the action and
// move
// the cluster state to the next step
currentState = ((InitializePolicyContextStep) currentStep).performAction(index, currentState);
currentState = ((ClusterStateActionStep) currentStep).performAction(index, currentState);
if (currentStep.getNextStepKey() == null) {
return currentState;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.indexlifecycle.AsyncActionStep;
import org.elasticsearch.xpack.core.indexlifecycle.AsyncWaitStep;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateActionStep;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateWaitStep;
import org.elasticsearch.xpack.core.indexlifecycle.ErrorStep;
import org.elasticsearch.xpack.core.indexlifecycle.InitializePolicyContextStep;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
import org.elasticsearch.xpack.core.indexlifecycle.Step;
Expand Down Expand Up @@ -67,7 +67,7 @@ public void runPolicy(String policy, IndexMetaData indexMetaData, ClusterState c
} else if (currentStep instanceof ErrorStep) {
logger.debug(
"policy [" + policy + "] for index [" + indexMetaData.getIndex().getName() + "] on an error step, skipping execution");
} else if (currentStep instanceof InitializePolicyContextStep || currentStep instanceof ClusterStateWaitStep) {
} else if (currentStep instanceof ClusterStateActionStep || currentStep instanceof ClusterStateWaitStep) {
executeClusterStateSteps(indexMetaData.getIndex(), policy, currentStep);
} else if (currentStep instanceof AsyncWaitStep) {
if (fromClusterStateChange == false) {
Expand Down Expand Up @@ -121,7 +121,7 @@ private void runPolicy(IndexMetaData indexMetaData, ClusterState currentState) {
}

private void executeClusterStateSteps(Index index, String policy, Step step) {
assert step instanceof InitializePolicyContextStep || step instanceof ClusterStateWaitStep;
assert step instanceof ClusterStateActionStep || step instanceof ClusterStateWaitStep;
clusterService.submitStateUpdateTask("ILM", new ExecuteStepsUpdateTask(policy, index, step, stepRegistry, nowSupplier));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import org.elasticsearch.xpack.core.indexlifecycle.TerminalPolicyStep;
import org.elasticsearch.xpack.core.indexlifecycle.TestLifecycleType;
import org.elasticsearch.xpack.indexlifecycle.IndexLifecycleRunnerTests.MockClusterStateWaitStep;
import org.elasticsearch.xpack.indexlifecycle.IndexLifecycleRunnerTests.MockInitializePolicyContextStep;
import org.elasticsearch.xpack.indexlifecycle.IndexLifecycleRunnerTests.MockClusterStateActionStep;
import org.junit.Before;
import org.mockito.Mockito;

Expand All @@ -57,7 +57,7 @@ public class ExecuteStepsUpdateTaskTests extends ESTestCase {
private String mixedPolicyName;
private String allClusterPolicyName;
private Index index;
private MockInitializePolicyContextStep firstStep;
private MockClusterStateActionStep firstStep;
private MockClusterStateWaitStep secondStep;
private MockClusterStateWaitStep allClusterSecondStep;
private MockStep thirdStep;
Expand All @@ -67,7 +67,7 @@ public class ExecuteStepsUpdateTaskTests extends ESTestCase {
public void prepareState() {
client = Mockito.mock(Client.class);
Mockito.when(client.settings()).thenReturn(Settings.EMPTY);
firstStep = new MockInitializePolicyContextStep(firstStepKey, secondStepKey);
firstStep = new MockClusterStateActionStep(firstStepKey, secondStepKey);
secondStep = new MockClusterStateWaitStep(secondStepKey, thirdStepKey);
secondStep.setWillComplete(true);
allClusterSecondStep = new MockClusterStateWaitStep(secondStepKey, TerminalPolicyStep.KEY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
import org.elasticsearch.xpack.core.indexlifecycle.AbstractStepTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.AsyncActionStep;
import org.elasticsearch.xpack.core.indexlifecycle.AsyncWaitStep;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateActionStep;
import org.elasticsearch.xpack.core.indexlifecycle.ClusterStateWaitStep;
import org.elasticsearch.xpack.core.indexlifecycle.ErrorStep;
import org.elasticsearch.xpack.core.indexlifecycle.InitializePolicyContextStep;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyMetadata;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
Expand Down Expand Up @@ -97,10 +97,10 @@ public void testRunPolicyErrorStep() {
Mockito.verifyZeroInteractions(clusterService);
}

public void testRunPolicyInitializePolicyContextStep() {
public void testRunPolicyClusterStateActionStep() {
String policyName = "cluster_state_action_policy";
StepKey stepKey = new StepKey("phase", "action", "cluster_state_action_step");
MockInitializePolicyContextStep step = new MockInitializePolicyContextStep(stepKey, null);
MockClusterStateActionStep step = new MockClusterStateActionStep(stepKey, null);
PolicyStepsRegistry stepRegistry = createOneStepPolicyStepRegistry(policyName, step);
ClusterService clusterService = mock(ClusterService.class);
IndexLifecycleRunner runner = new IndexLifecycleRunner(stepRegistry, clusterService, () -> 0L);
Expand Down Expand Up @@ -804,7 +804,7 @@ public void testSkipped() {
.put(LifecycleSettings.LIFECYCLE_ACTION, randomAlphaOfLength(5))
.put(LifecycleSettings.LIFECYCLE_STEP, randomAlphaOfLength(5))
.put(LifecycleSettings.LIFECYCLE_SKIP, true));
Step step = mock(randomFrom(TerminalPolicyStep.class, InitializePolicyContextStep.class,
Step step = mock(randomFrom(TerminalPolicyStep.class, ClusterStateActionStep.class,
ClusterStateWaitStep.class, AsyncActionStep.class, AsyncWaitStep.class));
PolicyStepsRegistry stepRegistry = createOneStepPolicyStepRegistry(policy, step);
ClusterService clusterService = mock(ClusterService.class);
Expand Down Expand Up @@ -1101,12 +1101,12 @@ public void evaluateCondition(Index index, Listener listener) {

}

static class MockInitializePolicyContextStep extends InitializePolicyContextStep {
static class MockClusterStateActionStep extends ClusterStateActionStep {

private RuntimeException exception;
private long executeCount = 0;

MockInitializePolicyContextStep(StepKey key, StepKey nextStepKey) {
MockClusterStateActionStep(StepKey key, StepKey nextStepKey) {
super(key, nextStepKey);
}

Expand Down
Loading