Skip to content
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
Expand Up @@ -96,9 +96,14 @@ public void runPeriodicStep(String policy, IndexMetaData indexMetaData) {
}
Step currentStep = getCurrentStep(stepRegistry, policy, indexMetaData, lifecycleState);
if (currentStep == null) {
logger.warn("current step [{}] for index [{}] with policy [{}] is not recognized",
getCurrentStepKey(lifecycleState), index, policy);
return;
if (stepRegistry.policyExists(policy) == false) {
markPolicyDoesNotExist(policy, indexMetaData.getIndex(), lifecycleState);
return;
} else {
logger.error("current step [{}] for index [{}] with policy [{}] is not recognized",
getCurrentStepKey(lifecycleState), index, policy);
return;
}
}

if (currentStep instanceof TerminalPolicyStep) {
Expand Down Expand Up @@ -197,9 +202,14 @@ public void runPolicyAfterStateChange(String policy, IndexMetaData indexMetaData
}
Step currentStep = getCurrentStep(stepRegistry, policy, indexMetaData, lifecycleState);
if (currentStep == null) {
logger.warn("current step [{}] for index [{}] with policy [{}] is not recognized",
getCurrentStepKey(lifecycleState), index, policy);
return;
if (stepRegistry.policyExists(policy) == false) {
markPolicyDoesNotExist(policy, indexMetaData.getIndex(), lifecycleState);
return;
} else {
logger.error("current step [{}] for index [{}] with policy [{}] is not recognized",
getCurrentStepKey(lifecycleState), index, policy);
return;
}
}

if (currentStep instanceof TerminalPolicyStep) {
Expand Down Expand Up @@ -536,4 +546,12 @@ private static IndexMetaData.Builder removePolicyForIndex(IndexMetaData indexMet
builder.removeCustom(ILM_CUSTOM_METADATA_KEY);
return builder.settings(newSettings);
}

private void markPolicyDoesNotExist(String policyName, Index index, LifecycleExecutionState executionState) {
logger.debug("policy [{}] for index [{}] does not exist, recording this in step_info for this index",
policyName, index.getName());
setStepInfo(index, policyName, getCurrentStepKey(executionState),
new SetStepInfoUpdateTask.ExceptionWrapper(
new IllegalArgumentException("policy [" + policyName + "] does not exist")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ public boolean stepExists(final String policy, final Step.StepKey stepKey) {
}
}

public boolean policyExists(final String policy) {
return lifecyclePolicyMap.containsKey(policy);
}

public Step getFirstStep(String policy) {
return firstStepMap.get(policy);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.Index;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleExecutionState;
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
import org.elasticsearch.xpack.core.indexlifecycle.Step;

import java.io.IOException;
import java.util.Objects;

public class SetStepInfoUpdateTask extends ClusterStateUpdateTask {
private final Index index;
Expand Down Expand Up @@ -58,7 +60,7 @@ public ClusterState execute(ClusterState currentState) throws IOException {
Settings indexSettings = idxMeta.getSettings();
LifecycleExecutionState indexILMData = LifecycleExecutionState.fromIndexMetadata(idxMeta);
if (policy.equals(LifecycleSettings.LIFECYCLE_NAME_SETTING.get(indexSettings))
&& currentStepKey.equals(IndexLifecycleRunner.getCurrentStepKey(indexILMData))) {
&& Objects.equals(currentStepKey, IndexLifecycleRunner.getCurrentStepKey(indexILMData))) {
return IndexLifecycleRunner.addStepInfoToClusterState(index, currentState, stepInfo);
} else {
// either the policy has changed or the step is now
Expand All @@ -73,4 +75,20 @@ public void onFailure(String source, Exception e) {
throw new ElasticsearchException("policy [" + policy + "] for index [" + index.getName()
+ "] failed trying to set step info for step [" + currentStepKey + "].", e);
}

public static class ExceptionWrapper implements ToXContentObject {
private final Throwable exception;

public ExceptionWrapper(Throwable exception) {
this.exception = exception;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
ElasticsearchException.generateThrowableXContent(builder, params, exception);
builder.endObject();
return builder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ public void testRunPolicyAsyncWaitStepClusterStateChangeIgnored() {
Mockito.verifyZeroInteractions(clusterService);
}

public void testRunPolicyWithNoStepsInRegistry() {
public void testRunPolicyThatDoesntExist() {
String policyName = "cluster_state_action_policy";
ClusterService clusterService = mock(ClusterService.class);
IndexLifecycleRunner runner = new IndexLifecycleRunner(new PolicyStepsRegistry(NamedXContentRegistry.EMPTY, null),
Expand All @@ -520,7 +520,16 @@ public void testRunPolicyWithNoStepsInRegistry() {
.numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
// verify that no exception is thrown
runner.runPolicyAfterStateChange(policyName, indexMetaData);
Mockito.verifyZeroInteractions(clusterService);
Mockito.verify(clusterService, Mockito.times(1)).submitStateUpdateTask(Mockito.matches("ilm-set-step-info"),
Mockito.argThat(new SetStepInfoUpdateTaskMatcher(indexMetaData.getIndex(), policyName, null,
(builder, params) -> {
builder.startObject();
builder.field("reason", "policy [does_not_exist] does not exist");
builder.field("type", "illegal_argument_exception");
builder.endObject();
return builder;
})));
Mockito.verifyNoMoreInteractions(clusterService);
}

public void testGetCurrentStepKey() {
Expand Down Expand Up @@ -1602,7 +1611,17 @@ public boolean matches(Object argument) {
return Objects.equals(index, task.getIndex()) &&
Objects.equals(policy, task.getPolicy())&&
Objects.equals(currentStepKey, task.getCurrentStepKey()) &&
Objects.equals(stepInfo, task.getStepInfo());
Objects.equals(xContentToString(stepInfo), xContentToString(task.getStepInfo()));
}

private String xContentToString(ToXContentObject xContent) {
try {
XContentBuilder builder = JsonXContent.contentBuilder();
stepInfo.toXContent(builder, ToXContent.EMPTY_PARAMS);
return BytesReference.bytes(builder).utf8ToString();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,60 @@ public void testShrinkAction() throws Exception {
expectThrows(ResponseException.class, this::indexDocument);
}

@SuppressWarnings("unchecked")
public void testNonexistentPolicy() throws Exception {
String indexPrefix = randomAlphaOfLengthBetween(5,15).toLowerCase(Locale.ROOT);
final StringEntity template = new StringEntity("{\n" +
" \"index_patterns\": \"" + indexPrefix + "*\",\n" +
" \"settings\": {\n" +
" \"index\": {\n" +
" \"lifecycle\": {\n" +
" \"name\": \"does_not_exist\",\n" +
" \"rollover_alias\": \"test_alias\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}", ContentType.APPLICATION_JSON);
Request templateRequest = new Request("PUT", "_template/test");
templateRequest.setEntity(template);
client().performRequest(templateRequest);

policy = randomAlphaOfLengthBetween(5,20);
createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L));

index = indexPrefix + "-000001";
final StringEntity putIndex = new StringEntity("{\n" +
" \"aliases\": {\n" +
" \"test_alias\": {\n" +
" \"is_write_index\": true\n" +
" }\n" +
" }\n" +
"}", ContentType.APPLICATION_JSON);
Request putIndexRequest = new Request("PUT", index);
putIndexRequest.setEntity(putIndex);
client().performRequest(putIndexRequest);
indexDocument();

assertBusy(() -> {
Request explainRequest = new Request("GET", index + "/_ilm/explain");
Response response = client().performRequest(explainRequest);
Map<String, Object> responseMap;
try (InputStream is = response.getEntity().getContent()) {
responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true);
}
logger.info(responseMap);
Map<String, Object> indexStatus = (Map<String, Object>)((Map<String, Object>) responseMap.get("indices")).get(index);
assertNull(indexStatus.get("phase"));
assertNull(indexStatus.get("action"));
assertNull(indexStatus.get("step"));
assertEquals("policy [does_not_exist] does not exist",
((Map<String, String>)indexStatus.get("step_info")).get("reason"));
assertEquals("illegal_argument_exception",
((Map<String, String>)indexStatus.get("step_info")).get("type"));
});

}

private void createNewSingletonPolicy(String phaseName, LifecycleAction action) throws IOException {
createNewSingletonPolicy(phaseName, action, TimeValue.ZERO);
}
Expand Down