From 7f4cc0eac201ff2925a9ad824d2fb14d5ac1fef4 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 18 Dec 2019 22:04:26 +0100 Subject: [PATCH 01/25] Snapshot action --- .../xpack/core/XPackClientPlugin.java | 2 + .../xpack/core/ilm/SnapshotAction.java | 92 +++++++++++++++++ .../xpack/core/ilm/WaitForSnapshotStep.java | 99 +++++++++++++++++++ .../xpack/core/ilm/SnapshotActionTests.java | 41 ++++++++ .../xpack/ilm/IndexLifecycle.java | 4 +- 5 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java create mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java index 9128f75a0937b..e01431ed33c3e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java @@ -54,6 +54,7 @@ import org.elasticsearch.xpack.core.ilm.RolloverAction; import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; +import org.elasticsearch.xpack.core.ilm.SnapshotAction; import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType; import org.elasticsearch.xpack.core.ilm.UnfollowAction; import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction; @@ -551,6 +552,7 @@ public List getNamedWriteables() { new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, UnfollowAction.NAME, UnfollowAction::new), + new NamedWriteableRegistry.Entry(LifecycleAction.class, SnapshotAction.NAME, SnapshotAction::new), // Data Frame new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.TRANSFORM, TransformFeatureSetUsage::new), new NamedWriteableRegistry.Entry(PersistentTaskParams.class, TransformField.TASK_NAME, TransformTaskParams::new), diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java new file mode 100644 index 0000000000000..267d873aa6b7d --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java @@ -0,0 +1,92 @@ +/* + * 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.ilm; + +import org.elasticsearch.client.Client; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.xpack.core.ilm.Step.StepKey; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class SnapshotAction implements LifecycleAction { + + public static final String NAME = "snapshot"; + public static final ParseField POLICY_FIELD = new ParseField("policy"); + + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, + a -> new SnapshotAction((String) a[0])); + + static { + PARSER.declareString(ConstructingObjectParser.constructorArg(), POLICY_FIELD); + } + + private final String policy; + + public static SnapshotAction parse(XContentParser parser) { + return PARSER.apply(parser, null); + } + + public SnapshotAction(String policy) { + if (policy == null) { + throw new IllegalArgumentException("Policy name must be specified"); + } + this.policy = policy; + } + + public SnapshotAction(StreamInput in) throws IOException { + this(in.readString()); + } + + @Override + public List toSteps(Client client, String phase, StepKey nextStepKey) { + StepKey waitForSnapshotKey = new StepKey(phase, NAME, WaitForSnapshotStep.NAME); + return Collections.singletonList(new WaitForSnapshotStep(waitForSnapshotKey, nextStepKey, client, policy)); + } + + @Override + public boolean isSafeAction() { + return true; + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(policy); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(POLICY_FIELD.getPreferredName(), policy); + builder.endObject(); + return builder; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SnapshotAction that = (SnapshotAction) o; + return policy.equals(that.policy); + } + + @Override + public int hashCode() { + return Objects.hash(policy); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java new file mode 100644 index 0000000000000..9d4b8ae5decb6 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java @@ -0,0 +1,99 @@ +/* + * 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.ilm; + +import org.elasticsearch.ResourceNotFoundException; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.xpack.core.ilm.action.ExplainLifecycleAction; +import org.elasticsearch.xpack.core.slm.action.GetSnapshotLifecycleAction; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +public class WaitForSnapshotStep extends AsyncWaitStep { + + static final String NAME = "wait-for-snapshot"; + + private static final String POLICY_NOT_EXECUTED_MESSAGE = "waiting for policy '%s' to be executed"; + private static final String POLICY_NOT_FOUND_MESSAGE = "policy '%s' not found, waiting for it to be created and executed"; + + private final String policy; + + WaitForSnapshotStep(StepKey key, StepKey nextStepKey, Client client, String policy) { + super(key, nextStepKey, client); + this.policy = policy; + } + + @Override + public void evaluateCondition(IndexMetaData indexMetaData, Listener listener) { + Client client = getClient(); + ResponseHandler handler = new ResponseHandler(listener); + + ExplainLifecycleRequest explainLifecycleReq = new ExplainLifecycleRequest(); + String index = indexMetaData.getIndex().getName(); + explainLifecycleReq.indices(index); + client.execute(ExplainLifecycleAction.INSTANCE, explainLifecycleReq, + ActionListener.wrap(r -> handler.handleResponse(-r.getIndexResponses().get(index).getPhaseTime()), listener::onFailure)); + + GetSnapshotLifecycleAction.Request getSnapshotReq = new GetSnapshotLifecycleAction.Request(policy); + client.execute(GetSnapshotLifecycleAction.INSTANCE, getSnapshotReq, + ActionListener.wrap(r -> handler.handleResponse(r.getPolicies().get(0).getLastSuccess().getTimestamp()), + e -> handleSnapshotRequestFailure(listener, e))); + } + + private void handleSnapshotRequestFailure(Listener listener, Exception e) { + if (e instanceof ResourceNotFoundException) { + listener.onResponse(false, new Info(POLICY_NOT_FOUND_MESSAGE)); + } else { + listener.onFailure(e); + } + } + + private final class ResponseHandler { + private final AtomicLong timeDifference = new AtomicLong(); + private final AtomicBoolean requestsFinished = new AtomicBoolean(); + private final Listener listener; + + + public ResponseHandler(Listener listener) { + this.listener = listener; + } + + private void handleResponse(long time) { + timeDifference.addAndGet(time); + if (requestsFinished.getAndSet(true)) { + if (timeDifference.get() > 0) { + listener.onResponse(true, null); + } else { + listener.onResponse(false, new Info(POLICY_NOT_EXECUTED_MESSAGE)); + } + } + } + } + + private final class Info implements ToXContentObject { + + private static final String MESSAGE_FIELD = "message"; + private final String message; + + private Info(String message) { + this.message = message; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(MESSAGE_FIELD, String.format(message, policy)); + builder.endObject(); + return builder; + } + } +} diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java new file mode 100644 index 0000000000000..30755f20cb3d5 --- /dev/null +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java @@ -0,0 +1,41 @@ +package org.elasticsearch.xpack.core.ilm; + +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +public class SnapshotActionTests extends AbstractActionTestCase { + + @Override + public void testToSteps() { + SnapshotAction action = createTestInstance(); + Step.StepKey nextStep = new Step.StepKey("", "", ""); + List steps = action.toSteps(null, "delete", nextStep); + assertEquals(1, steps.size()); + Step step = steps.get(0); + assertTrue(step instanceof WaitForSnapshotStep); + assertEquals(nextStep, step.getNextStepKey()); + + Step.StepKey key = step.getKey(); + assertEquals("delete", key.getPhase()); + assertEquals(SnapshotAction.NAME, key.getAction()); + assertEquals(WaitForSnapshotStep.NAME, key.getName()); + } + + @Override + protected SnapshotAction doParseInstance(XContentParser parser) throws IOException { + return SnapshotAction.parse(parser); + } + + @Override + protected SnapshotAction createTestInstance() { + return new SnapshotAction("policy"); + } + + @Override + protected Writeable.Reader instanceReader() { + return SnapshotAction::new; + } +} diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java index 394174ed673f6..922256c40c117 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java @@ -50,6 +50,7 @@ import org.elasticsearch.xpack.core.ilm.RolloverAction; import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; +import org.elasticsearch.xpack.core.ilm.SnapshotAction; import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType; import org.elasticsearch.xpack.core.ilm.UnfollowAction; import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction; @@ -217,7 +218,8 @@ public List getNa new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse), - new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(UnfollowAction.NAME), UnfollowAction::parse) + new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(UnfollowAction.NAME), UnfollowAction::parse), + new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SnapshotAction.NAME), SnapshotAction::parse) ); } From b282be65b52dffda968057309812963bccf49691 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 20 Dec 2019 21:27:37 +0100 Subject: [PATCH 02/25] ILM action to wait for SLM policy execution This change add new ILM action to wait for SLM policy execution to ensure that index has snapshot before deletion. Closes #45067. --- .../xpack/core/ilm/SnapshotAction.java | 2 +- .../core/ilm/TimeseriesLifecycleType.java | 2 +- .../xpack/core/ilm/WaitForSnapshotStep.java | 102 +++---- .../xpack/core/ilm/SnapshotActionTests.java | 5 + .../core/ilm/WaitForSnapshotStepTests.java | 154 ++++++++++ .../ilm/TimeSeriesLifecycleActionsIT.java | 271 ++++++++++-------- 6 files changed, 358 insertions(+), 178 deletions(-) create mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java index 267d873aa6b7d..152230ddf4180 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java @@ -51,7 +51,7 @@ public SnapshotAction(StreamInput in) throws IOException { @Override public List toSteps(Client client, String phase, StepKey nextStepKey) { StepKey waitForSnapshotKey = new StepKey(phase, NAME, WaitForSnapshotStep.NAME); - return Collections.singletonList(new WaitForSnapshotStep(waitForSnapshotKey, nextStepKey, client, policy)); + return Collections.singletonList(new WaitForSnapshotStep(waitForSnapshotKey, nextStepKey, policy)); } @Override diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java index b2948df6373b4..8a8dffdaba03f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java @@ -37,7 +37,7 @@ public class TimeseriesLifecycleType implements LifecycleType { AllocateAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME); static final List ORDERED_VALID_COLD_ACTIONS = Arrays.asList(SetPriorityAction.NAME, UnfollowAction.NAME, AllocateAction.NAME, FreezeAction.NAME); - static final List ORDERED_VALID_DELETE_ACTIONS = Arrays.asList(DeleteAction.NAME); + static final List ORDERED_VALID_DELETE_ACTIONS = Arrays.asList(SnapshotAction.NAME, DeleteAction.NAME); static final Set VALID_HOT_ACTIONS = Sets.newHashSet(ORDERED_VALID_HOT_ACTIONS); static final Set VALID_WARM_ACTIONS = Sets.newHashSet(ORDERED_VALID_WARM_ACTIONS); static final Set VALID_COLD_ACTIONS = Sets.newHashSet(ORDERED_VALID_COLD_ACTIONS); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java index 9d4b8ae5decb6..69e807f21087a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java @@ -5,95 +5,69 @@ */ package org.elasticsearch.xpack.core.ilm; -import org.elasticsearch.ResourceNotFoundException; -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.xcontent.ToXContentObject; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.xpack.core.ilm.action.ExplainLifecycleAction; -import org.elasticsearch.xpack.core.slm.action.GetSnapshotLifecycleAction; +import org.elasticsearch.index.Index; +import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata; +import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata; -import java.io.IOException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; +import java.util.Objects; -public class WaitForSnapshotStep extends AsyncWaitStep { +public class WaitForSnapshotStep extends ClusterStateWaitStep { static final String NAME = "wait-for-snapshot"; + private static final String MESSAGE_FIELD = "message"; private static final String POLICY_NOT_EXECUTED_MESSAGE = "waiting for policy '%s' to be executed"; private static final String POLICY_NOT_FOUND_MESSAGE = "policy '%s' not found, waiting for it to be created and executed"; private final String policy; - WaitForSnapshotStep(StepKey key, StepKey nextStepKey, Client client, String policy) { - super(key, nextStepKey, client); + WaitForSnapshotStep(StepKey key, StepKey nextStepKey, String policy) { + super(key, nextStepKey); this.policy = policy; } @Override - public void evaluateCondition(IndexMetaData indexMetaData, Listener listener) { - Client client = getClient(); - ResponseHandler handler = new ResponseHandler(listener); + public Result isConditionMet(Index index, ClusterState clusterState) { + long phaseTime = LifecycleExecutionState.fromIndexMetadata(clusterState.metaData().index(index)).getPhaseTime(); - ExplainLifecycleRequest explainLifecycleReq = new ExplainLifecycleRequest(); - String index = indexMetaData.getIndex().getName(); - explainLifecycleReq.indices(index); - client.execute(ExplainLifecycleAction.INSTANCE, explainLifecycleReq, - ActionListener.wrap(r -> handler.handleResponse(-r.getIndexResponses().get(index).getPhaseTime()), listener::onFailure)); - - GetSnapshotLifecycleAction.Request getSnapshotReq = new GetSnapshotLifecycleAction.Request(policy); - client.execute(GetSnapshotLifecycleAction.INSTANCE, getSnapshotReq, - ActionListener.wrap(r -> handler.handleResponse(r.getPolicies().get(0).getLastSuccess().getTimestamp()), - e -> handleSnapshotRequestFailure(listener, e))); - } - - private void handleSnapshotRequestFailure(Listener listener, Exception e) { - if (e instanceof ResourceNotFoundException) { - listener.onResponse(false, new Info(POLICY_NOT_FOUND_MESSAGE)); - } else { - listener.onFailure(e); + SnapshotLifecycleMetadata snapMeta = clusterState.metaData().custom(SnapshotLifecycleMetadata.TYPE); + if (snapMeta == null || snapMeta.getSnapshotConfigurations().containsKey(policy) == false) { + return new Result(false, info(POLICY_NOT_FOUND_MESSAGE)); } - } - - private final class ResponseHandler { - private final AtomicLong timeDifference = new AtomicLong(); - private final AtomicBoolean requestsFinished = new AtomicBoolean(); - private final Listener listener; - - - public ResponseHandler(Listener listener) { - this.listener = listener; + SnapshotLifecyclePolicyMetadata snapPolicyMeta = snapMeta.getSnapshotConfigurations().get(policy); + if (snapPolicyMeta.getLastSuccess() == null || snapPolicyMeta.getLastSuccess().getTimestamp() < phaseTime) { + return new Result(false, info(POLICY_NOT_EXECUTED_MESSAGE)); } - private void handleResponse(long time) { - timeDifference.addAndGet(time); - if (requestsFinished.getAndSet(true)) { - if (timeDifference.get() > 0) { - listener.onResponse(true, null); - } else { - listener.onResponse(false, new Info(POLICY_NOT_EXECUTED_MESSAGE)); - } - } - } + return new Result(true, null); } - private final class Info implements ToXContentObject { - - private static final String MESSAGE_FIELD = "message"; - private final String message; - - private Info(String message) { - this.message = message; - } + public String getPolicy() { + return policy; + } - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + private ToXContentObject info(String message) { + return (builder, params) -> { builder.startObject(); builder.field(MESSAGE_FIELD, String.format(message, policy)); builder.endObject(); return builder; - } + }; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + WaitForSnapshotStep that = (WaitForSnapshotStep) o; + return policy.equals(that.policy); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), policy); } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java index 30755f20cb3d5..0391b34210dca 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java @@ -1,3 +1,8 @@ +/* + * 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.ilm; import org.elasticsearch.common.io.stream.Writeable; diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java new file mode 100644 index 0000000000000..615093cb918eb --- /dev/null +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java @@ -0,0 +1,154 @@ +/* + * 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.ilm; + +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.collect.ImmutableOpenMap; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord; +import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata; +import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy; +import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +public class WaitForSnapshotStepTests extends AbstractStepTestCase { + + @Override + protected WaitForSnapshotStep createRandomInstance() { + return new WaitForSnapshotStep(randomStepKey(), randomStepKey(), randomAlphaOfLengthBetween(1, 10)); + } + + @Override + protected WaitForSnapshotStep mutateInstance(WaitForSnapshotStep instance) { + Step.StepKey key = instance.getKey(); + Step.StepKey nextKey = instance.getNextStepKey(); + String policy = instance.getPolicy(); + + switch (between(0, 2)) { + case 0: + key = new Step.StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5)); + break; + case 1: + nextKey = new Step.StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5)); + break; + case 2: + policy = randomAlphaOfLengthBetween(1, 10); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + + return new WaitForSnapshotStep(key, nextKey, policy); + } + + @Override + protected WaitForSnapshotStep copyInstance(WaitForSnapshotStep instance) { + return new WaitForSnapshotStep(instance.getKey(), instance.getNextStepKey(), instance.getPolicy()); + } + + public void testNoSlmPolicies() throws IOException { + IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10)) + .putCustom(LifecycleExecutionState.ILM_CUSTOM_METADATA_KEY, Map.of("phase_time", Long.toString(randomLong()))) + .settings(settings(Version.CURRENT)) + .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build(); + ImmutableOpenMap.Builder indices = + ImmutableOpenMap.builder().fPut(indexMetaData.getIndex().getName(), indexMetaData); + MetaData.Builder meta = MetaData.builder().indices(indices.build()); + ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(meta).build(); + WaitForSnapshotStep instance = createRandomInstance(); + ClusterStateWaitStep.Result result = instance.isConditionMet(indexMetaData.getIndex(), clusterState); + assertFalse(result.isComplete()); + assertTrue(getMessage(result).contains("not found")); + } + + public void testSlmPolicyNotExecuted() throws IOException { + WaitForSnapshotStep instance = createRandomInstance(); + SnapshotLifecyclePolicyMetadata slmPolicy = SnapshotLifecyclePolicyMetadata.builder() + .setModifiedDate(randomLong()) + .setPolicy(new SnapshotLifecyclePolicy("", "", "", "", null, null)) + .build(); + SnapshotLifecycleMetadata smlMetaData = new SnapshotLifecycleMetadata(Map.of(instance.getPolicy(), slmPolicy), + OperationMode.RUNNING, null); + + + IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10)) + .putCustom(LifecycleExecutionState.ILM_CUSTOM_METADATA_KEY, Map.of("phase_time", Long.toString(randomLong()))) + .settings(settings(Version.CURRENT)) + .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build(); + ImmutableOpenMap.Builder indices = + ImmutableOpenMap.builder().fPut(indexMetaData.getIndex().getName(), indexMetaData); + MetaData.Builder meta = MetaData.builder().indices(indices.build()).putCustom(SnapshotLifecycleMetadata.TYPE, smlMetaData); + ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(meta).build(); + ClusterStateWaitStep.Result result = instance.isConditionMet(indexMetaData.getIndex(), clusterState); + assertFalse(result.isComplete()); + assertTrue(getMessage(result).contains("to be executed")); + } + + public void testSlmPolicyExecutedBeforeStep() throws IOException { + long phaseTime = randomLong(); + + WaitForSnapshotStep instance = createRandomInstance(); + SnapshotLifecyclePolicyMetadata slmPolicy = SnapshotLifecyclePolicyMetadata.builder() + .setModifiedDate(randomLong()) + .setPolicy(new SnapshotLifecyclePolicy("", "", "", "", null, null)) + .setLastSuccess(new SnapshotInvocationRecord("", phaseTime - 10, "")) + .build(); + SnapshotLifecycleMetadata smlMetaData = new SnapshotLifecycleMetadata(Map.of(instance.getPolicy(), slmPolicy), + OperationMode.RUNNING, null); + + IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10)) + .putCustom(LifecycleExecutionState.ILM_CUSTOM_METADATA_KEY, Map.of("phase_time", Long.toString(phaseTime))) + .settings(settings(Version.CURRENT)) + .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build(); + ImmutableOpenMap.Builder indices = + ImmutableOpenMap.builder().fPut(indexMetaData.getIndex().getName(), indexMetaData); + MetaData.Builder meta = MetaData.builder().indices(indices.build()).putCustom(SnapshotLifecycleMetadata.TYPE, smlMetaData); + ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(meta).build(); + ClusterStateWaitStep.Result result = instance.isConditionMet(indexMetaData.getIndex(), clusterState); + assertFalse(result.isComplete()); + assertTrue(getMessage(result).contains("to be executed")); + } + + public void testSlmPolicyExecutedAfterStep() throws IOException { + long phaseTime = randomLong(); + + WaitForSnapshotStep instance = createRandomInstance(); + SnapshotLifecyclePolicyMetadata slmPolicy = SnapshotLifecyclePolicyMetadata.builder() + .setModifiedDate(randomLong()) + .setPolicy(new SnapshotLifecyclePolicy("", "", "", "", null, null)) + .setLastSuccess(new SnapshotInvocationRecord("", phaseTime + 10, "")) + .build(); + SnapshotLifecycleMetadata smlMetaData = new SnapshotLifecycleMetadata(Map.of(instance.getPolicy(), slmPolicy), + OperationMode.RUNNING, null); + + IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10)) + .putCustom(LifecycleExecutionState.ILM_CUSTOM_METADATA_KEY, Map.of("phase_time", Long.toString(phaseTime))) + .settings(settings(Version.CURRENT)) + .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build(); + ImmutableOpenMap.Builder indices = + ImmutableOpenMap.builder().fPut(indexMetaData.getIndex().getName(), indexMetaData); + MetaData.Builder meta = MetaData.builder().indices(indices.build()).putCustom(SnapshotLifecycleMetadata.TYPE, smlMetaData); + ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(meta).build(); + ClusterStateWaitStep.Result result = instance.isConditionMet(indexMetaData.getIndex(), clusterState); + assertTrue(result.isComplete()); + assertNull(result.getInfomationContext()); + } + + private String getMessage(ClusterStateWaitStep.Result result) throws IOException { + XContentBuilder s = result.getInfomationContext().toXContent(JsonXContent.contentBuilder(), null); + s.flush(); + return new String(((ByteArrayOutputStream) s.getOutputStream()).toByteArray(), StandardCharsets.UTF_8); + } +} diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index 4e160c69efd13..569ce63e09d62 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -37,6 +37,7 @@ import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.ShrinkStep; +import org.elasticsearch.xpack.core.ilm.SnapshotAction; import org.elasticsearch.xpack.core.ilm.Step.StepKey; import org.elasticsearch.xpack.core.ilm.TerminalPolicyStep; import org.hamcrest.Matchers; @@ -81,7 +82,7 @@ public void refreshIndex() { public static void updatePolicy(String indexName, String policy) throws IOException { Request changePolicyRequest = new Request("PUT", "/" + indexName + "/_settings"); final StringEntity changePolicyEntity = new StringEntity("{ \"index.lifecycle.name\": \"" + policy + "\" }", - ContentType.APPLICATION_JSON); + ContentType.APPLICATION_JSON); changePolicyRequest.setEntity(changePolicyEntity); assertOK(client().performRequest(changePolicyRequest)); } @@ -317,6 +318,82 @@ public void testAllocateActionOnlyReplicas() throws Exception { }); } + public void testWaitForSnapshot() throws Exception { + createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); + createNewSingletonPolicy("delete", new SnapshotAction("slm")); + updatePolicy(index, policy); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); + + createSnapshotRepo(); + createSlmPolicy(); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + + Request request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("completed"))); + } + + public void testWaitForSnapshotSlmExecutedBefore() throws Exception { + createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); + createNewSingletonPolicy("delete", new SnapshotAction("slm")); + + createSnapshotRepo(); + createSlmPolicy(); + + Request request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + updatePolicy(index, policy); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + + request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("completed"))); + } + + private void createSlmPolicy() throws IOException { + Request request; + request = new Request("PUT", "/_slm/policy/slm"); + request.setJsonEntity(Strings + .toString(JsonXContent.contentBuilder() + .startObject() + .field("schedule", "59 59 23 31 12 ? 2099") + .field("repository", "repo") + .field("name", "snap" + randomAlphaOfLengthBetween(5, 10).toLowerCase()) + .startObject("config") + .endObject() + .endObject())); + + assertOK(client().performRequest(request)); + } + + private void createSnapshotRepo() throws IOException { + Request request = new Request("PUT", "/_snapshot/repo"); + request.setJsonEntity(Strings + .toString(JsonXContent.contentBuilder() + .startObject() + .field("type", "fs") + .startObject("settings") + .field("compress", randomBoolean()) + .field("location", System.getProperty("tests.path.repo")) + .field("max_snapshot_bytes_per_sec", "256b") + .endObject() + .endObject())); + assertOK(client().performRequest(request)); + } + public void testDelete() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); @@ -340,18 +417,8 @@ public void testDeleteOnlyShouldNotMakeIndexReadonly() throws Exception { public void testDeleteDuringSnapshot() throws Exception { // Create the repository before taking the snapshot. - Request request = new Request("PUT", "/_snapshot/repo"); - request.setJsonEntity(Strings - .toString(JsonXContent.contentBuilder() - .startObject() - .field("type", "fs") - .startObject("settings") - .field("compress", randomBoolean()) - .field("location", System.getProperty("tests.path.repo")) - .field("max_snapshot_bytes_per_sec", "256b") - .endObject() - .endObject())); - assertOK(client().performRequest(request)); + createSnapshotRepo(); + Request request; // create delete policy createNewSingletonPolicy("delete", new DeleteAction(), TimeValue.timeValueMillis(0)); // create index without policy @@ -466,18 +533,8 @@ public void testShrinkSameShards() throws Exception { public void testShrinkDuringSnapshot() throws Exception { String shrunkenIndex = ShrinkAction.SHRUNKEN_INDEX_PREFIX + index; // Create the repository before taking the snapshot. - Request request = new Request("PUT", "/_snapshot/repo"); - request.setJsonEntity(Strings - .toString(JsonXContent.contentBuilder() - .startObject() - .field("type", "fs") - .startObject("settings") - .field("compress", randomBoolean()) - .field("location", System.getProperty("tests.path.repo")) - .field("max_snapshot_bytes_per_sec", "256b") - .endObject() - .endObject())); - assertOK(client().performRequest(request)); + createSnapshotRepo(); + Request request; // create delete policy createNewSingletonPolicy("warm", new ShrinkAction(1), TimeValue.timeValueMillis(0)); // create index without policy @@ -527,18 +584,8 @@ public void testFreezeAction() throws Exception { public void testFreezeDuringSnapshot() throws Exception { // Create the repository before taking the snapshot. - Request request = new Request("PUT", "/_snapshot/repo"); - request.setJsonEntity(Strings - .toString(JsonXContent.contentBuilder() - .startObject() - .field("type", "fs") - .startObject("settings") - .field("compress", randomBoolean()) - .field("location", System.getProperty("tests.path.repo")) - .field("max_snapshot_bytes_per_sec", "256b") - .endObject() - .endObject())); - assertOK(client().performRequest(request)); + createSnapshotRepo(); + Request request; // create delete policy createNewSingletonPolicy("cold", new FreezeAction(), TimeValue.timeValueMillis(0)); // create index without policy @@ -593,7 +640,7 @@ public void testSetNullPriority() throws Exception { @SuppressWarnings("unchecked") public void testNonexistentPolicy() throws Exception { - String indexPrefix = randomAlphaOfLengthBetween(5,15).toLowerCase(Locale.ROOT); + String indexPrefix = randomAlphaOfLengthBetween(5, 15).toLowerCase(Locale.ROOT); final StringEntity template = new StringEntity("{\n" + " \"index_patterns\": \"" + indexPrefix + "*\",\n" + " \"settings\": {\n" + @@ -609,7 +656,7 @@ public void testNonexistentPolicy() throws Exception { templateRequest.setEntity(template); client().performRequest(templateRequest); - policy = randomAlphaOfLengthBetween(5,20); + policy = randomAlphaOfLengthBetween(5, 20); createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L)); index = indexPrefix + "-000001"; @@ -633,7 +680,7 @@ public void testNonexistentPolicy() throws Exception { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } logger.info(responseMap); - Map indexStatus = (Map)((Map) responseMap.get("indices")).get(index); + Map indexStatus = (Map) ((Map) responseMap.get("indices")).get(index); assertNull(indexStatus.get("phase")); assertNull(indexStatus.get("action")); assertNull(indexStatus.get("step")); @@ -647,11 +694,11 @@ public void testNonexistentPolicy() throws Exception { public void testInvalidPolicyNames() { ResponseException ex; - policy = randomAlphaOfLengthBetween(0,10) + "," + randomAlphaOfLengthBetween(0,10); + policy = randomAlphaOfLengthBetween(0, 10) + "," + randomAlphaOfLengthBetween(0, 10); ex = expectThrows(ResponseException.class, () -> createNewSingletonPolicy("delete", new DeleteAction())); assertThat(ex.getMessage(), containsString("invalid policy name")); - policy = randomAlphaOfLengthBetween(0,10) + "%20" + randomAlphaOfLengthBetween(0,10); + policy = randomAlphaOfLengthBetween(0, 10) + "%20" + randomAlphaOfLengthBetween(0, 10); ex = expectThrows(ResponseException.class, () -> createNewSingletonPolicy("delete", new DeleteAction())); assertThat(ex.getMessage(), containsString("invalid policy name")); @@ -677,15 +724,15 @@ public void testDeletePolicyInUse() throws IOException { createNewSingletonPolicy("delete", new DeleteAction(), TimeValue.timeValueHours(13)); createIndexWithSettingsNoAlias(managedIndex1, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), originalPolicy)); createIndexWithSettingsNoAlias(managedIndex2, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), originalPolicy)); createIndexWithSettingsNoAlias(unmanagedIndex, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10))); + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10))); createIndexWithSettingsNoAlias(managedByOtherPolicyIndex, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), otherPolicy)); Request deleteRequest = new Request("DELETE", "_ilm/policy/" + originalPolicy); @@ -812,7 +859,7 @@ public void testMoveToStepRereadsPolicy() throws Exception { public void testCanStopILMWithPolicyUsingNonexistentPolicy() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) - .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), randomAlphaOfLengthBetween(5,15))); + .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), randomAlphaOfLengthBetween(5, 15))); Request stopILMRequest = new Request("POST", "_ilm/stop"); assertOK(client().performRequest(stopILMRequest)); @@ -867,7 +914,7 @@ public void testExplainFilters() throws Exception { ); createIndexWithSettingsNoAlias(nonexistantPolicyIndex, Settings.builder() .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) - .put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3,10)))); + .put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3, 10)))); createIndexWithSettingsNoAlias(unmanagedIndex, Settings.builder() .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); @@ -937,74 +984,74 @@ public void testILMRolloverRetriesOnReadOnlyBlock() throws Exception { assertBusy(() -> assertThat(getStepKeyForIndex(firstIndex), equalTo(TerminalPolicyStep.KEY))); } - public void testILMRolloverOnManuallyRolledIndex() throws Exception { - String originalIndex = index + "-000001"; - String secondIndex = index + "-000002"; - String thirdIndex = index + "-000003"; - - // Set up a policy with rollover - createNewSingletonPolicy("hot", new RolloverAction(null, null, 2L)); - Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); - createIndexTemplate.setJsonEntity("{" + - "\"index_patterns\": [\""+ index + "-*\"], \n" + - " \"settings\": {\n" + - " \"number_of_shards\": 1,\n" + - " \"number_of_replicas\": 0,\n" + - " \"index.lifecycle.name\": \"" + policy+ "\", \n" + - " \"index.lifecycle.rollover_alias\": \"alias\"\n" + - " }\n" + - "}"); - client().performRequest(createIndexTemplate); - - createIndexWithSettings( - originalIndex, - Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) - .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), - true - ); - - // Index a document - index(client(), originalIndex, "1", "foo", "bar"); - Request refreshOriginalIndex = new Request("POST", "/" + originalIndex + "/_refresh"); - client().performRequest(refreshOriginalIndex); - - // Manual rollover - Request rolloverRequest = new Request("POST", "/alias/_rollover"); - rolloverRequest.setJsonEntity("{\n" + - " \"conditions\": {\n" + - " \"max_docs\": \"1\"\n" + - " }\n" + - "}" - ); - client().performRequest(rolloverRequest); - assertBusy(() -> assertTrue(indexExists(secondIndex))); - - // Index another document into the original index so the ILM rollover policy condition is met - index(client(), originalIndex, "2", "foo", "bar"); - client().performRequest(refreshOriginalIndex); - - // Wait for the rollover policy to execute - assertBusy(() -> assertThat(getStepKeyForIndex(originalIndex), equalTo(TerminalPolicyStep.KEY))); - - // ILM should manage the second index after attempting (and skipping) rolling the original index - assertBusy(() -> assertTrue((boolean) explainIndex(secondIndex).getOrDefault("managed", true))); - - // index some documents to trigger an ILM rollover - index(client(), "alias", "1", "foo", "bar"); - index(client(), "alias", "2", "foo", "bar"); - index(client(), "alias", "3", "foo", "bar"); - Request refreshSecondIndex = new Request("POST", "/" + secondIndex + "/_refresh"); - client().performRequest(refreshSecondIndex).getStatusLine(); - - // ILM should rollover the second index even though it skipped the first one - assertBusy(() -> assertThat(getStepKeyForIndex(secondIndex), equalTo(TerminalPolicyStep.KEY))); - assertBusy(() -> assertTrue(indexExists(thirdIndex))); - } + public void testILMRolloverOnManuallyRolledIndex() throws Exception { + String originalIndex = index + "-000001"; + String secondIndex = index + "-000002"; + String thirdIndex = index + "-000003"; + + // Set up a policy with rollover + createNewSingletonPolicy("hot", new RolloverAction(null, null, 2L)); + Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\"" + index + "-*\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy + "\", \n" + + " \"index.lifecycle.rollover_alias\": \"alias\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + createIndexWithSettings( + originalIndex, + Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), + true + ); + + // Index a document + index(client(), originalIndex, "1", "foo", "bar"); + Request refreshOriginalIndex = new Request("POST", "/" + originalIndex + "/_refresh"); + client().performRequest(refreshOriginalIndex); + + // Manual rollover + Request rolloverRequest = new Request("POST", "/alias/_rollover"); + rolloverRequest.setJsonEntity("{\n" + + " \"conditions\": {\n" + + " \"max_docs\": \"1\"\n" + + " }\n" + + "}" + ); + client().performRequest(rolloverRequest); + assertBusy(() -> assertTrue(indexExists(secondIndex))); + + // Index another document into the original index so the ILM rollover policy condition is met + index(client(), originalIndex, "2", "foo", "bar"); + client().performRequest(refreshOriginalIndex); + + // Wait for the rollover policy to execute + assertBusy(() -> assertThat(getStepKeyForIndex(originalIndex), equalTo(TerminalPolicyStep.KEY))); + + // ILM should manage the second index after attempting (and skipping) rolling the original index + assertBusy(() -> assertTrue((boolean) explainIndex(secondIndex).getOrDefault("managed", true))); + + // index some documents to trigger an ILM rollover + index(client(), "alias", "1", "foo", "bar"); + index(client(), "alias", "2", "foo", "bar"); + index(client(), "alias", "3", "foo", "bar"); + Request refreshSecondIndex = new Request("POST", "/" + secondIndex + "/_refresh"); + client().performRequest(refreshSecondIndex).getStatusLine(); + + // ILM should rollover the second index even though it skipped the first one + assertBusy(() -> assertThat(getStepKeyForIndex(secondIndex), equalTo(TerminalPolicyStep.KEY))); + assertBusy(() -> assertTrue(indexExists(thirdIndex))); + } private void createFullPolicy(TimeValue hotTime) throws IOException { Map hotActions = new HashMap<>(); hotActions.put(SetPriorityAction.NAME, new SetPriorityAction(100)); - hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, 1L)); + hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, 1L)); Map warmActions = new HashMap<>(); warmActions.put(SetPriorityAction.NAME, new SetPriorityAction(50)); warmActions.put(ForceMergeAction.NAME, new ForceMergeAction(1)); From 30a6e8a87d3c6acf8e439f290d9a361d4f573624 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 20 Dec 2019 22:26:06 +0100 Subject: [PATCH 03/25] merge fix --- .../core/ilm/WaitForSnapshotStepTests.java | 5 +- .../ilm/TimeSeriesLifecycleActionsIT.java | 202 ++++++++++++++++-- 2 files changed, 188 insertions(+), 19 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java index 615093cb918eb..d07dd3234f897 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java @@ -10,6 +10,7 @@ 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.collect.ImmutableOpenMap; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.json.JsonXContent; @@ -147,8 +148,6 @@ public void testSlmPolicyExecutedAfterStep() throws IOException { } private String getMessage(ClusterStateWaitStep.Result result) throws IOException { - XContentBuilder s = result.getInfomationContext().toXContent(JsonXContent.contentBuilder(), null); - s.flush(); - return new String(((ByteArrayOutputStream) s.getOutputStream()).toByteArray(), StandardCharsets.UTF_8); + return Strings.toString(result.getInfomationContext()); } } diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index 569ce63e09d62..28ed923217999 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -8,13 +8,14 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -38,8 +39,10 @@ import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.ShrinkStep; import org.elasticsearch.xpack.core.ilm.SnapshotAction; +import org.elasticsearch.xpack.core.ilm.Step; import org.elasticsearch.xpack.core.ilm.Step.StepKey; import org.elasticsearch.xpack.core.ilm.TerminalPolicyStep; +import org.elasticsearch.xpack.core.ilm.WaitForRolloverReadyStep; import org.hamcrest.Matchers; import org.junit.Before; @@ -394,6 +397,7 @@ private void createSnapshotRepo() throws IOException { assertOK(client().performRequest(request)); } + public void testDelete() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); @@ -640,7 +644,7 @@ public void testSetNullPriority() throws Exception { @SuppressWarnings("unchecked") public void testNonexistentPolicy() throws Exception { - String indexPrefix = randomAlphaOfLengthBetween(5, 15).toLowerCase(Locale.ROOT); + String indexPrefix = randomAlphaOfLengthBetween(5,15).toLowerCase(Locale.ROOT); final StringEntity template = new StringEntity("{\n" + " \"index_patterns\": \"" + indexPrefix + "*\",\n" + " \"settings\": {\n" + @@ -656,7 +660,7 @@ public void testNonexistentPolicy() throws Exception { templateRequest.setEntity(template); client().performRequest(templateRequest); - policy = randomAlphaOfLengthBetween(5, 20); + policy = randomAlphaOfLengthBetween(5,20); createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L)); index = indexPrefix + "-000001"; @@ -680,7 +684,7 @@ public void testNonexistentPolicy() throws Exception { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } logger.info(responseMap); - Map indexStatus = (Map) ((Map) responseMap.get("indices")).get(index); + Map indexStatus = (Map)((Map) responseMap.get("indices")).get(index); assertNull(indexStatus.get("phase")); assertNull(indexStatus.get("action")); assertNull(indexStatus.get("step")); @@ -694,11 +698,11 @@ public void testNonexistentPolicy() throws Exception { public void testInvalidPolicyNames() { ResponseException ex; - policy = randomAlphaOfLengthBetween(0, 10) + "," + randomAlphaOfLengthBetween(0, 10); + policy = randomAlphaOfLengthBetween(0,10) + "," + randomAlphaOfLengthBetween(0,10); ex = expectThrows(ResponseException.class, () -> createNewSingletonPolicy("delete", new DeleteAction())); assertThat(ex.getMessage(), containsString("invalid policy name")); - policy = randomAlphaOfLengthBetween(0, 10) + "%20" + randomAlphaOfLengthBetween(0, 10); + policy = randomAlphaOfLengthBetween(0,10) + "%20" + randomAlphaOfLengthBetween(0,10); ex = expectThrows(ResponseException.class, () -> createNewSingletonPolicy("delete", new DeleteAction())); assertThat(ex.getMessage(), containsString("invalid policy name")); @@ -724,15 +728,15 @@ public void testDeletePolicyInUse() throws IOException { createNewSingletonPolicy("delete", new DeleteAction(), TimeValue.timeValueHours(13)); createIndexWithSettingsNoAlias(managedIndex1, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)) .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), originalPolicy)); createIndexWithSettingsNoAlias(managedIndex2, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)) .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), originalPolicy)); createIndexWithSettingsNoAlias(unmanagedIndex, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10))); + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10))); createIndexWithSettingsNoAlias(managedByOtherPolicyIndex, Settings.builder() - .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)) .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), otherPolicy)); Request deleteRequest = new Request("DELETE", "_ilm/policy/" + originalPolicy); @@ -859,7 +863,7 @@ public void testMoveToStepRereadsPolicy() throws Exception { public void testCanStopILMWithPolicyUsingNonexistentPolicy() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) - .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), randomAlphaOfLengthBetween(5, 15))); + .put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), randomAlphaOfLengthBetween(5,15))); Request stopILMRequest = new Request("POST", "_ilm/stop"); assertOK(client().performRequest(stopILMRequest)); @@ -914,7 +918,7 @@ public void testExplainFilters() throws Exception { ); createIndexWithSettingsNoAlias(nonexistantPolicyIndex, Settings.builder() .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) - .put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3, 10)))); + .put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3,10)))); createIndexWithSettingsNoAlias(unmanagedIndex, Settings.builder() .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); @@ -993,11 +997,11 @@ public void testILMRolloverOnManuallyRolledIndex() throws Exception { createNewSingletonPolicy("hot", new RolloverAction(null, null, 2L)); Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); createIndexTemplate.setJsonEntity("{" + - "\"index_patterns\": [\"" + index + "-*\"], \n" + + "\"index_patterns\": [\""+ index + "-*\"], \n" + " \"settings\": {\n" + " \"number_of_shards\": 1,\n" + " \"number_of_replicas\": 0,\n" + - " \"index.lifecycle.name\": \"" + policy + "\", \n" + + " \"index.lifecycle.name\": \"" + policy+ "\", \n" + " \"index.lifecycle.rollover_alias\": \"alias\"\n" + " }\n" + "}"); @@ -1048,10 +1052,176 @@ public void testILMRolloverOnManuallyRolledIndex() throws Exception { assertBusy(() -> assertTrue(indexExists(thirdIndex))); } + public void testHistoryIsWrittenWithSuccess() throws Exception { + String index = "index"; + + createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L)); + Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "-*\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\",\n" + + " \"index.lifecycle.rollover_alias\": \"alias\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + createIndexWithSettings(index + "-1", + Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), + true); + + // Index a document + index(client(), index + "-1", "1", "foo", "bar"); + Request refreshIndex = new Request("POST", "/" + index + "-1/_refresh"); + client().performRequest(refreshIndex); + + 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-yellow-step"), 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, "update-rollover-lifecycle-date"), 30, TimeUnit.SECONDS); + assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "set-indexing-complete"), 30, TimeUnit.SECONDS); + assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "completed"), 30, TimeUnit.SECONDS); + + assertBusy(() -> assertHistoryIsPresent(policy, index + "-000002", true, "check-rollover-ready"), 30, TimeUnit.SECONDS); + } + + public void testHistoryIsWrittenWithFailure() throws Exception { + String index = "index"; + + createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L)); + Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "-*\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + createIndexWithSettings(index + "-1", + Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), + false); + + // Index a document + index(client(), index + "-1", "1", "foo", "bar"); + Request refreshIndex = new Request("POST", "/" + index + "-1/_refresh"); + client().performRequest(refreshIndex); + + assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", false, "ERROR"), 30, TimeUnit.SECONDS); + } + + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/50353") + public void testHistoryIsWrittenWithDeletion() throws Exception { + String index = "index"; + + createNewSingletonPolicy("delete", new DeleteAction()); + Request createIndexTemplate = new Request("PUT", "_template/delete_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + // Index should be created and then deleted by ILM + createIndexWithSettings(index, Settings.builder(), false); + + assertBusy(() -> { + logger.info("--> checking for index deletion..."); + Request existCheck = new Request("HEAD", "/" + index); + Response resp = client().performRequest(existCheck); + assertThat(resp.getStatusLine().getStatusCode(), equalTo(404)); + }); + + assertBusy(() -> { + assertHistoryIsPresent(policy, index, true, "delete", "delete", "wait-for-shard-history-leases"); + assertHistoryIsPresent(policy, index, true, "delete", "delete", "complete"); + }, 30, TimeUnit.SECONDS); + } + + // This method should be called inside an assertBusy, it has no retry logic of its own + private void assertHistoryIsPresent(String policyName, String indexName, boolean success, String stepName) throws IOException { + assertHistoryIsPresent(policyName, indexName, success, null, null, stepName); + } + + // This method should be called inside an assertBusy, it has no retry logic of its own + private void assertHistoryIsPresent(String policyName, String indexName, boolean success, + @Nullable String phase, @Nullable String action, String stepName) throws IOException { + logger.info("--> checking for history item [{}], [{}], success: [{}], phase: [{}], action: [{}], step: [{}]", + policyName, indexName, success, phase, action, stepName); + final Request historySearchRequest = new Request("GET", "ilm-history*/_search"); + historySearchRequest.setJsonEntity("{\n" + + " \"query\": {\n" + + " \"bool\": {\n" + + " \"must\": [\n" + + " {\n" + + " \"term\": {\n" + + " \"policy\": \"" + policyName + "\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"term\": {\n" + + " \"success\": " + success + "\n" + + " }\n" + + " },\n" + + " {\n" + + " \"term\": {\n" + + " \"index\": \"" + indexName + "\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"term\": {\n" + + " \"state.step\": \"" + stepName + "\"\n" + + " }\n" + + " }\n" + + (phase == null ? "" : ",{\"term\": {\"state.phase\": \"" + phase + "\"}}") + + (action == null ? "" : ",{\"term\": {\"state.action\": \"" + action + "\"}}") + + " ]\n" + + " }\n" + + " }\n" + + "}"); + Response historyResponse; + try { + historyResponse = client().performRequest(historySearchRequest); + Map historyResponseMap; + try (InputStream is = historyResponse.getEntity().getContent()) { + historyResponseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); + } + logger.info("--> history response: {}", historyResponseMap); + assertThat((int)((Map) ((Map) historyResponseMap.get("hits")).get("total")).get("value"), + greaterThanOrEqualTo(1)); + } catch (ResponseException e) { + // Throw AssertionError instead of an exception if the search fails so that assertBusy works as expected + logger.error(e); + fail("failed to perform search:" + e.getMessage()); + } + + // Finally, check that the history index is in a good state + Step.StepKey stepKey = getStepKeyForIndex("ilm-history-1-000001"); + assertEquals("hot", stepKey.getPhase()); + assertEquals(RolloverAction.NAME, stepKey.getAction()); + assertEquals(WaitForRolloverReadyStep.NAME, stepKey.getName()); + } + private void createFullPolicy(TimeValue hotTime) throws IOException { Map hotActions = new HashMap<>(); hotActions.put(SetPriorityAction.NAME, new SetPriorityAction(100)); - hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, 1L)); + hotActions.put(RolloverAction.NAME, new RolloverAction(null, null, 1L)); Map warmActions = new HashMap<>(); warmActions.put(SetPriorityAction.NAME, new SetPriorityAction(50)); warmActions.put(ForceMergeAction.NAME, new ForceMergeAction(1)); From f4fab83c7f5e8b44d3017a09c44ae0e7147df4ba Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 20 Dec 2019 22:30:33 +0100 Subject: [PATCH 04/25] tests --- .../ilm/TimeSeriesLifecycleActionsIT.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index a2ba9e727071a..e624032f28bec 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -37,6 +37,7 @@ import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.ShrinkStep; +import org.elasticsearch.xpack.core.ilm.SnapshotAction; import org.elasticsearch.xpack.core.ilm.Step.StepKey; import org.elasticsearch.xpack.core.ilm.TerminalPolicyStep; import org.hamcrest.Matchers; @@ -317,6 +318,83 @@ public void testAllocateActionOnlyReplicas() throws Exception { }); } + public void testWaitForSnapshot() throws Exception { + createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); + createNewSingletonPolicy("delete", new SnapshotAction("slm")); + updatePolicy(index, policy); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); + + createSnapshotRepo(); + createSlmPolicy(); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + + Request request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("completed"))); + } + + public void testWaitForSnapshotSlmExecutedBefore() throws Exception { + createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); + createNewSingletonPolicy("delete", new SnapshotAction("slm")); + + createSnapshotRepo(); + createSlmPolicy(); + + Request request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + updatePolicy(index, policy); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + + request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + request = new Request("PUT", "/_slm/policy/slm/_execute"); + assertOK(client().performRequest(request)); + + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("completed"))); + } + + private void createSlmPolicy() throws IOException { + Request request; + request = new Request("PUT", "/_slm/policy/slm"); + request.setJsonEntity(Strings + .toString(JsonXContent.contentBuilder() + .startObject() + .field("schedule", "59 59 23 31 12 ? 2099") + .field("repository", "repo") + .field("name", "snap" + randomAlphaOfLengthBetween(5, 10).toLowerCase()) + .startObject("config") + .endObject() + .endObject())); + + assertOK(client().performRequest(request)); + } + + private void createSnapshotRepo() throws IOException { + Request request = new Request("PUT", "/_snapshot/repo"); + request.setJsonEntity(Strings + .toString(JsonXContent.contentBuilder() + .startObject() + .field("type", "fs") + .startObject("settings") + .field("compress", randomBoolean()) + .field("location", System.getProperty("tests.path.repo")) + .field("max_snapshot_bytes_per_sec", "256b") + .endObject() + .endObject())); + assertOK(client().performRequest(request)); + } + + public void testDelete() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); From 94942b46a4251226d1ddb1a6734cd7dca6dc5856 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 20 Dec 2019 22:32:44 +0100 Subject: [PATCH 05/25] tests --- .../ilm/TimeSeriesLifecycleActionsIT.java | 173 +++++++++++++++++- 1 file changed, 171 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index e624032f28bec..d45c1fc7b21ea 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -8,13 +8,14 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; @@ -38,8 +39,10 @@ import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.ShrinkStep; import org.elasticsearch.xpack.core.ilm.SnapshotAction; +import org.elasticsearch.xpack.core.ilm.Step; import org.elasticsearch.xpack.core.ilm.Step.StepKey; import org.elasticsearch.xpack.core.ilm.TerminalPolicyStep; +import org.elasticsearch.xpack.core.ilm.WaitForRolloverReadyStep; import org.hamcrest.Matchers; import org.junit.Before; @@ -1079,6 +1082,172 @@ public void testILMRolloverOnManuallyRolledIndex() throws Exception { assertBusy(() -> assertTrue(indexExists(thirdIndex))); } + public void testHistoryIsWrittenWithSuccess() throws Exception { + String index = "index"; + + createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L)); + Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "-*\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\",\n" + + " \"index.lifecycle.rollover_alias\": \"alias\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + createIndexWithSettings(index + "-1", + Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), + true); + + // Index a document + index(client(), index + "-1", "1", "foo", "bar"); + Request refreshIndex = new Request("POST", "/" + index + "-1/_refresh"); + client().performRequest(refreshIndex); + + 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-yellow-step"), 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, "update-rollover-lifecycle-date"), 30, TimeUnit.SECONDS); + assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "set-indexing-complete"), 30, TimeUnit.SECONDS); + assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", true, "completed"), 30, TimeUnit.SECONDS); + + assertBusy(() -> assertHistoryIsPresent(policy, index + "-000002", true, "check-rollover-ready"), 30, TimeUnit.SECONDS); + } + + public void testHistoryIsWrittenWithFailure() throws Exception { + String index = "index"; + + createNewSingletonPolicy("hot", new RolloverAction(null, null, 1L)); + Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "-*\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + createIndexWithSettings(index + "-1", + Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), + false); + + // Index a document + index(client(), index + "-1", "1", "foo", "bar"); + Request refreshIndex = new Request("POST", "/" + index + "-1/_refresh"); + client().performRequest(refreshIndex); + + assertBusy(() -> assertHistoryIsPresent(policy, index + "-1", false, "ERROR"), 30, TimeUnit.SECONDS); + } + + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/50353") + public void testHistoryIsWrittenWithDeletion() throws Exception { + String index = "index"; + + createNewSingletonPolicy("delete", new DeleteAction()); + Request createIndexTemplate = new Request("PUT", "_template/delete_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + // Index should be created and then deleted by ILM + createIndexWithSettings(index, Settings.builder(), false); + + assertBusy(() -> { + logger.info("--> checking for index deletion..."); + Request existCheck = new Request("HEAD", "/" + index); + Response resp = client().performRequest(existCheck); + assertThat(resp.getStatusLine().getStatusCode(), equalTo(404)); + }); + + assertBusy(() -> { + assertHistoryIsPresent(policy, index, true, "delete", "delete", "wait-for-shard-history-leases"); + assertHistoryIsPresent(policy, index, true, "delete", "delete", "complete"); + }, 30, TimeUnit.SECONDS); + } + + // This method should be called inside an assertBusy, it has no retry logic of its own + private void assertHistoryIsPresent(String policyName, String indexName, boolean success, String stepName) throws IOException { + assertHistoryIsPresent(policyName, indexName, success, null, null, stepName); + } + + // This method should be called inside an assertBusy, it has no retry logic of its own + private void assertHistoryIsPresent(String policyName, String indexName, boolean success, + @Nullable String phase, @Nullable String action, String stepName) throws IOException { + logger.info("--> checking for history item [{}], [{}], success: [{}], phase: [{}], action: [{}], step: [{}]", + policyName, indexName, success, phase, action, stepName); + final Request historySearchRequest = new Request("GET", "ilm-history*/_search"); + historySearchRequest.setJsonEntity("{\n" + + " \"query\": {\n" + + " \"bool\": {\n" + + " \"must\": [\n" + + " {\n" + + " \"term\": {\n" + + " \"policy\": \"" + policyName + "\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"term\": {\n" + + " \"success\": " + success + "\n" + + " }\n" + + " },\n" + + " {\n" + + " \"term\": {\n" + + " \"index\": \"" + indexName + "\"\n" + + " }\n" + + " },\n" + + " {\n" + + " \"term\": {\n" + + " \"state.step\": \"" + stepName + "\"\n" + + " }\n" + + " }\n" + + (phase == null ? "" : ",{\"term\": {\"state.phase\": \"" + phase + "\"}}") + + (action == null ? "" : ",{\"term\": {\"state.action\": \"" + action + "\"}}") + + " ]\n" + + " }\n" + + " }\n" + + "}"); + Response historyResponse; + try { + historyResponse = client().performRequest(historySearchRequest); + Map historyResponseMap; + try (InputStream is = historyResponse.getEntity().getContent()) { + historyResponseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); + } + logger.info("--> history response: {}", historyResponseMap); + assertThat((int)((Map) ((Map) historyResponseMap.get("hits")).get("total")).get("value"), + greaterThanOrEqualTo(1)); + } catch (ResponseException e) { + // Throw AssertionError instead of an exception if the search fails so that assertBusy works as expected + logger.error(e); + fail("failed to perform search:" + e.getMessage()); + } + + // Finally, check that the history index is in a good state + Step.StepKey stepKey = getStepKeyForIndex("ilm-history-1-000001"); + assertEquals("hot", stepKey.getPhase()); + assertEquals(RolloverAction.NAME, stepKey.getAction()); + assertEquals(WaitForRolloverReadyStep.NAME, stepKey.getName()); + } + private void createFullPolicy(TimeValue hotTime) throws IOException { Map hotActions = new HashMap<>(); hotActions.put(SetPriorityAction.NAME, new SetPriorityAction(100)); From 9ca8d85b53ac8828f36b514c4875788cf23d50da Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 20 Dec 2019 22:35:22 +0100 Subject: [PATCH 06/25] spaces fix --- .../ilm/TimeSeriesLifecycleActionsIT.java | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index d45c1fc7b21ea..dab851485dd0d 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -85,7 +85,7 @@ public void refreshIndex() { public static void updatePolicy(String indexName, String policy) throws IOException { Request changePolicyRequest = new Request("PUT", "/" + indexName + "/_settings"); final StringEntity changePolicyEntity = new StringEntity("{ \"index.lifecycle.name\": \"" + policy + "\" }", - ContentType.APPLICATION_JSON); + ContentType.APPLICATION_JSON); changePolicyRequest.setEntity(changePolicyEntity); assertOK(client().performRequest(changePolicyRequest)); } @@ -1018,69 +1018,69 @@ public void testILMRolloverRetriesOnReadOnlyBlock() throws Exception { assertBusy(() -> assertThat(getStepKeyForIndex(firstIndex), equalTo(TerminalPolicyStep.KEY))); } - public void testILMRolloverOnManuallyRolledIndex() throws Exception { - String originalIndex = index + "-000001"; - String secondIndex = index + "-000002"; - String thirdIndex = index + "-000003"; - - // Set up a policy with rollover - createNewSingletonPolicy("hot", new RolloverAction(null, null, 2L)); - Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); - createIndexTemplate.setJsonEntity("{" + - "\"index_patterns\": [\""+ index + "-*\"], \n" + - " \"settings\": {\n" + - " \"number_of_shards\": 1,\n" + - " \"number_of_replicas\": 0,\n" + - " \"index.lifecycle.name\": \"" + policy+ "\", \n" + - " \"index.lifecycle.rollover_alias\": \"alias\"\n" + - " }\n" + - "}"); - client().performRequest(createIndexTemplate); - - createIndexWithSettings( - originalIndex, - Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) - .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), - true - ); - - // Index a document - index(client(), originalIndex, "1", "foo", "bar"); - Request refreshOriginalIndex = new Request("POST", "/" + originalIndex + "/_refresh"); - client().performRequest(refreshOriginalIndex); - - // Manual rollover - Request rolloverRequest = new Request("POST", "/alias/_rollover"); - rolloverRequest.setJsonEntity("{\n" + - " \"conditions\": {\n" + - " \"max_docs\": \"1\"\n" + - " }\n" + - "}" - ); - client().performRequest(rolloverRequest); - assertBusy(() -> assertTrue(indexExists(secondIndex))); - - // Index another document into the original index so the ILM rollover policy condition is met - index(client(), originalIndex, "2", "foo", "bar"); - client().performRequest(refreshOriginalIndex); - - // Wait for the rollover policy to execute - assertBusy(() -> assertThat(getStepKeyForIndex(originalIndex), equalTo(TerminalPolicyStep.KEY))); - - // ILM should manage the second index after attempting (and skipping) rolling the original index - assertBusy(() -> assertTrue((boolean) explainIndex(secondIndex).getOrDefault("managed", true))); - - // index some documents to trigger an ILM rollover - index(client(), "alias", "1", "foo", "bar"); - index(client(), "alias", "2", "foo", "bar"); - index(client(), "alias", "3", "foo", "bar"); - Request refreshSecondIndex = new Request("POST", "/" + secondIndex + "/_refresh"); - client().performRequest(refreshSecondIndex).getStatusLine(); - - // ILM should rollover the second index even though it skipped the first one - assertBusy(() -> assertThat(getStepKeyForIndex(secondIndex), equalTo(TerminalPolicyStep.KEY))); - assertBusy(() -> assertTrue(indexExists(thirdIndex))); - } + public void testILMRolloverOnManuallyRolledIndex() throws Exception { + String originalIndex = index + "-000001"; + String secondIndex = index + "-000002"; + String thirdIndex = index + "-000003"; + + // Set up a policy with rollover + createNewSingletonPolicy("hot", new RolloverAction(null, null, 2L)); + Request createIndexTemplate = new Request("PUT", "_template/rolling_indexes"); + createIndexTemplate.setJsonEntity("{" + + "\"index_patterns\": [\""+ index + "-*\"], \n" + + " \"settings\": {\n" + + " \"number_of_shards\": 1,\n" + + " \"number_of_replicas\": 0,\n" + + " \"index.lifecycle.name\": \"" + policy+ "\", \n" + + " \"index.lifecycle.rollover_alias\": \"alias\"\n" + + " }\n" + + "}"); + client().performRequest(createIndexTemplate); + + createIndexWithSettings( + originalIndex, + Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0), + true + ); + + // Index a document + index(client(), originalIndex, "1", "foo", "bar"); + Request refreshOriginalIndex = new Request("POST", "/" + originalIndex + "/_refresh"); + client().performRequest(refreshOriginalIndex); + + // Manual rollover + Request rolloverRequest = new Request("POST", "/alias/_rollover"); + rolloverRequest.setJsonEntity("{\n" + + " \"conditions\": {\n" + + " \"max_docs\": \"1\"\n" + + " }\n" + + "}" + ); + client().performRequest(rolloverRequest); + assertBusy(() -> assertTrue(indexExists(secondIndex))); + + // Index another document into the original index so the ILM rollover policy condition is met + index(client(), originalIndex, "2", "foo", "bar"); + client().performRequest(refreshOriginalIndex); + + // Wait for the rollover policy to execute + assertBusy(() -> assertThat(getStepKeyForIndex(originalIndex), equalTo(TerminalPolicyStep.KEY))); + + // ILM should manage the second index after attempting (and skipping) rolling the original index + assertBusy(() -> assertTrue((boolean) explainIndex(secondIndex).getOrDefault("managed", true))); + + // index some documents to trigger an ILM rollover + index(client(), "alias", "1", "foo", "bar"); + index(client(), "alias", "2", "foo", "bar"); + index(client(), "alias", "3", "foo", "bar"); + Request refreshSecondIndex = new Request("POST", "/" + secondIndex + "/_refresh"); + client().performRequest(refreshSecondIndex).getStatusLine(); + + // ILM should rollover the second index even though it skipped the first one + assertBusy(() -> assertThat(getStepKeyForIndex(secondIndex), equalTo(TerminalPolicyStep.KEY))); + assertBusy(() -> assertTrue(indexExists(thirdIndex))); + } public void testHistoryIsWrittenWithSuccess() throws Exception { String index = "index"; From de255134fd3abff64a9b4ec369b47ee2b8a6c408 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 20 Dec 2019 23:10:43 +0100 Subject: [PATCH 07/25] unused imports removed --- .../xpack/core/ilm/WaitForSnapshotStepTests.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java index d07dd3234f897..43bba6d670ef5 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java @@ -12,16 +12,12 @@ import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord; import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata; import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy; import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.Map; public class WaitForSnapshotStepTests extends AbstractStepTestCase { From dc33fd12cc1854709a0370e97f9d24a4599e6211 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Thu, 2 Jan 2020 22:52:14 +0100 Subject: [PATCH 08/25] Review comments --- .../xpack/core/XPackClientPlugin.java | 4 +-- .../core/ilm/TimeseriesLifecycleType.java | 2 +- ...Action.java => WaitForSnapshotAction.java} | 19 ++++++------ .../xpack/core/ilm/WaitForSnapshotStep.java | 31 +++++++++++++++---- ...s.java => WaitForSnapshotActionTests.java} | 23 ++++++++------ .../ilm/TimeSeriesLifecycleActionsIT.java | 7 +++-- .../xpack/ilm/IndexLifecycle.java | 4 +-- 7 files changed, 58 insertions(+), 32 deletions(-) rename x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/{SnapshotAction.java => WaitForSnapshotAction.java} (78%) rename x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/{SnapshotActionTests.java => WaitForSnapshotActionTests.java} (55%) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java index 5363e6885fea4..1e3803050a984 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java @@ -54,7 +54,7 @@ import org.elasticsearch.xpack.core.ilm.RolloverAction; import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; -import org.elasticsearch.xpack.core.ilm.SnapshotAction; +import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction; import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType; import org.elasticsearch.xpack.core.ilm.UnfollowAction; import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction; @@ -536,7 +536,7 @@ public List getNamedWriteables() { new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, SetPriorityAction.NAME, SetPriorityAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, UnfollowAction.NAME, UnfollowAction::new), - new NamedWriteableRegistry.Entry(LifecycleAction.class, SnapshotAction.NAME, SnapshotAction::new), + new NamedWriteableRegistry.Entry(LifecycleAction.class, WaitForSnapshotAction.NAME, WaitForSnapshotAction::new), // Data Frame new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.TRANSFORM, TransformFeatureSetUsage::new), new NamedWriteableRegistry.Entry(PersistentTaskParams.class, TransformField.TASK_NAME, TransformTaskParams::new), diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java index 8a8dffdaba03f..ac5b3f51287b5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleType.java @@ -37,7 +37,7 @@ public class TimeseriesLifecycleType implements LifecycleType { AllocateAction.NAME, ShrinkAction.NAME, ForceMergeAction.NAME); static final List ORDERED_VALID_COLD_ACTIONS = Arrays.asList(SetPriorityAction.NAME, UnfollowAction.NAME, AllocateAction.NAME, FreezeAction.NAME); - static final List ORDERED_VALID_DELETE_ACTIONS = Arrays.asList(SnapshotAction.NAME, DeleteAction.NAME); + static final List ORDERED_VALID_DELETE_ACTIONS = Arrays.asList(WaitForSnapshotAction.NAME, DeleteAction.NAME); static final Set VALID_HOT_ACTIONS = Sets.newHashSet(ORDERED_VALID_HOT_ACTIONS); static final Set VALID_WARM_ACTIONS = Sets.newHashSet(ORDERED_VALID_WARM_ACTIONS); static final Set VALID_COLD_ACTIONS = Sets.newHashSet(ORDERED_VALID_COLD_ACTIONS); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java similarity index 78% rename from x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java rename to x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java index 152230ddf4180..cbd6edd4cb9ec 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java @@ -7,6 +7,7 @@ import org.elasticsearch.client.Client; import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ConstructingObjectParser; @@ -19,13 +20,13 @@ import java.util.List; import java.util.Objects; -public class SnapshotAction implements LifecycleAction { +public class WaitForSnapshotAction implements LifecycleAction { public static final String NAME = "snapshot"; public static final ParseField POLICY_FIELD = new ParseField("policy"); - private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, - a -> new SnapshotAction((String) a[0])); + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, + a -> new WaitForSnapshotAction((String) a[0])); static { PARSER.declareString(ConstructingObjectParser.constructorArg(), POLICY_FIELD); @@ -33,18 +34,18 @@ public class SnapshotAction implements LifecycleAction { private final String policy; - public static SnapshotAction parse(XContentParser parser) { + public static WaitForSnapshotAction parse(XContentParser parser) { return PARSER.apply(parser, null); } - public SnapshotAction(String policy) { - if (policy == null) { - throw new IllegalArgumentException("Policy name must be specified"); + public WaitForSnapshotAction(String policy) { + if (Strings.hasText(policy) == false) { + throw new IllegalArgumentException("policy name must be specified"); } this.policy = policy; } - public SnapshotAction(StreamInput in) throws IOException { + public WaitForSnapshotAction(StreamInput in) throws IOException { this(in.readString()); } @@ -81,7 +82,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - SnapshotAction that = (SnapshotAction) o; + WaitForSnapshotAction that = (WaitForSnapshotAction) o; return policy.equals(that.policy); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java index 69e807f21087a..01ba784159633 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java @@ -6,11 +6,14 @@ package org.elasticsearch.xpack.core.ilm; import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.index.Index; import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata; import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata; +import java.time.Instant; +import java.util.Locale; import java.util.Objects; public class WaitForSnapshotStep extends ClusterStateWaitStep { @@ -18,8 +21,10 @@ public class WaitForSnapshotStep extends ClusterStateWaitStep { static final String NAME = "wait-for-snapshot"; private static final String MESSAGE_FIELD = "message"; - private static final String POLICY_NOT_EXECUTED_MESSAGE = "waiting for policy '%s' to be executed"; + private static final String POLICY_NOT_EXECUTED_MESSAGE = "waiting for policy '%s' to be executed since %s"; private static final String POLICY_NOT_FOUND_MESSAGE = "policy '%s' not found, waiting for it to be created and executed"; + private static final String NO_INDEX_METADATA_MESSAGE = "no index metadata found for index '%s'"; + private static final String NO_PHASE_TIME_MESSAGE = "no information about ILM phase start in index metadata for index '%s'"; private final String policy; @@ -30,15 +35,24 @@ public class WaitForSnapshotStep extends ClusterStateWaitStep { @Override public Result isConditionMet(Index index, ClusterState clusterState) { - long phaseTime = LifecycleExecutionState.fromIndexMetadata(clusterState.metaData().index(index)).getPhaseTime(); + IndexMetaData indexMetaData = clusterState.metaData().index(index); + if (indexMetaData == null) { + throw new IllegalStateException(String.format(Locale.ROOT, NO_INDEX_METADATA_MESSAGE, index.getName())); + } + + Long phaseTime = LifecycleExecutionState.fromIndexMetadata(indexMetaData).getPhaseTime(); + + if (phaseTime == null) { + throw new IllegalStateException(String.format(Locale.ROOT, NO_PHASE_TIME_MESSAGE, index.getName())); + } SnapshotLifecycleMetadata snapMeta = clusterState.metaData().custom(SnapshotLifecycleMetadata.TYPE); if (snapMeta == null || snapMeta.getSnapshotConfigurations().containsKey(policy) == false) { - return new Result(false, info(POLICY_NOT_FOUND_MESSAGE)); + throw new IllegalStateException(POLICY_NOT_FOUND_MESSAGE); } SnapshotLifecyclePolicyMetadata snapPolicyMeta = snapMeta.getSnapshotConfigurations().get(policy); if (snapPolicyMeta.getLastSuccess() == null || snapPolicyMeta.getLastSuccess().getTimestamp() < phaseTime) { - return new Result(false, info(POLICY_NOT_EXECUTED_MESSAGE)); + return new Result(false, notExecutedMessage(phaseTime)); } return new Result(true, null); @@ -48,10 +62,15 @@ public String getPolicy() { return policy; } - private ToXContentObject info(String message) { + @Override + public boolean isRetryable() { + return true; + } + + private ToXContentObject notExecutedMessage(long time) { return (builder, params) -> { builder.startObject(); - builder.field(MESSAGE_FIELD, String.format(message, policy)); + builder.field(MESSAGE_FIELD, String.format(Locale.ROOT, POLICY_NOT_EXECUTED_MESSAGE, policy, Instant.ofEpochMilli(time))); builder.endObject(); return builder; }; diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java similarity index 55% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java rename to x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java index 0391b34210dca..bd74f9b1d2911 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/SnapshotActionTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java @@ -11,11 +11,11 @@ import java.io.IOException; import java.util.List; -public class SnapshotActionTests extends AbstractActionTestCase { +public class WaitForSnapshotActionTests extends AbstractActionTestCase { @Override public void testToSteps() { - SnapshotAction action = createTestInstance(); + WaitForSnapshotAction action = createTestInstance(); Step.StepKey nextStep = new Step.StepKey("", "", ""); List steps = action.toSteps(null, "delete", nextStep); assertEquals(1, steps.size()); @@ -25,22 +25,27 @@ public void testToSteps() { Step.StepKey key = step.getKey(); assertEquals("delete", key.getPhase()); - assertEquals(SnapshotAction.NAME, key.getAction()); + assertEquals(WaitForSnapshotAction.NAME, key.getAction()); assertEquals(WaitForSnapshotStep.NAME, key.getName()); } @Override - protected SnapshotAction doParseInstance(XContentParser parser) throws IOException { - return SnapshotAction.parse(parser); + protected WaitForSnapshotAction doParseInstance(XContentParser parser) throws IOException { + return WaitForSnapshotAction.parse(parser); } @Override - protected SnapshotAction createTestInstance() { - return new SnapshotAction("policy"); + protected WaitForSnapshotAction createTestInstance() { + return new WaitForSnapshotAction(randomAlphaOfLengthBetween(5, 10)); } @Override - protected Writeable.Reader instanceReader() { - return SnapshotAction::new; + protected Writeable.Reader instanceReader() { + return WaitForSnapshotAction::new; + } + + @Override + protected WaitForSnapshotAction mutateInstance(WaitForSnapshotAction instance) throws IOException { + return new WaitForSnapshotAction(randomAlphaOfLengthBetween(5, 10)); } } diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index dab851485dd0d..799ea94ae1879 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -38,7 +38,7 @@ import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.ShrinkStep; -import org.elasticsearch.xpack.core.ilm.SnapshotAction; +import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction; import org.elasticsearch.xpack.core.ilm.Step; import org.elasticsearch.xpack.core.ilm.Step.StepKey; import org.elasticsearch.xpack.core.ilm.TerminalPolicyStep; @@ -324,10 +324,11 @@ public void testAllocateActionOnlyReplicas() throws Exception { public void testWaitForSnapshot() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); - createNewSingletonPolicy("delete", new SnapshotAction("slm")); + createNewSingletonPolicy("delete", new WaitForSnapshotAction("slm")); updatePolicy(index, policy); assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); + assertBusy(() -> assertThat(getFailedStepForIndex(index), equalTo("wait-for-snapshot"))); createSnapshotRepo(); createSlmPolicy(); @@ -343,7 +344,7 @@ public void testWaitForSnapshot() throws Exception { public void testWaitForSnapshotSlmExecutedBefore() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); - createNewSingletonPolicy("delete", new SnapshotAction("slm")); + createNewSingletonPolicy("delete", new WaitForSnapshotAction("slm")); createSnapshotRepo(); createSlmPolicy(); diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java index 456cba6f8a679..feb00972c35c1 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java @@ -50,7 +50,7 @@ import org.elasticsearch.xpack.core.ilm.RolloverAction; import org.elasticsearch.xpack.core.ilm.SetPriorityAction; import org.elasticsearch.xpack.core.ilm.ShrinkAction; -import org.elasticsearch.xpack.core.ilm.SnapshotAction; +import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction; import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType; import org.elasticsearch.xpack.core.ilm.UnfollowAction; import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction; @@ -229,7 +229,7 @@ public List getNa new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(UnfollowAction.NAME), UnfollowAction::parse), - new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SnapshotAction.NAME), SnapshotAction::parse) + new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse) ); } From fa141424cee2a0aa578341d63ac7cdf2a0a9f67c Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Thu, 2 Jan 2020 23:13:02 +0100 Subject: [PATCH 09/25] Date foramtting --- .../org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java index 01ba784159633..8fef7e18263cc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java @@ -12,7 +12,7 @@ import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata; import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyMetadata; -import java.time.Instant; +import java.util.Date; import java.util.Locale; import java.util.Objects; @@ -70,7 +70,7 @@ public boolean isRetryable() { private ToXContentObject notExecutedMessage(long time) { return (builder, params) -> { builder.startObject(); - builder.field(MESSAGE_FIELD, String.format(Locale.ROOT, POLICY_NOT_EXECUTED_MESSAGE, policy, Instant.ofEpochMilli(time))); + builder.field(MESSAGE_FIELD, String.format(Locale.ROOT, POLICY_NOT_EXECUTED_MESSAGE, policy, new Date(time))); builder.endObject(); return builder; }; From 9ecb8b5005663faca79fc1e8503dd280a294c40a Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Thu, 2 Jan 2020 23:59:52 +0100 Subject: [PATCH 10/25] Fixed toLowerCase in test --- .../elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index 799ea94ae1879..9a702fab6f5ac 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -375,7 +375,7 @@ private void createSlmPolicy() throws IOException { .startObject() .field("schedule", "59 59 23 31 12 ? 2099") .field("repository", "repo") - .field("name", "snap" + randomAlphaOfLengthBetween(5, 10).toLowerCase()) + .field("name", "snap" + randomAlphaOfLengthBetween(5, 10).toLowerCase(Locale.ROOT)) .startObject("config") .endObject() .endObject())); From 19e5865348bfb7326bc7a45636dce3496530b56a Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 00:24:43 +0100 Subject: [PATCH 11/25] Test fix --- .../xpack/core/ilm/TimeseriesLifecycleTypeTests.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java index a76a22fcc7821..3186a545f23a9 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/TimeseriesLifecycleTypeTests.java @@ -34,6 +34,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase { private static final AllocateAction TEST_ALLOCATE_ACTION = new AllocateAction(2, Collections.singletonMap("node", "node1"),null, null); private static final DeleteAction TEST_DELETE_ACTION = new DeleteAction(); + private static final WaitForSnapshotAction TEST_WAIT_FOR_SNAPSHOT_ACTION = new WaitForSnapshotAction("policy"); private static final ForceMergeAction TEST_FORCE_MERGE_ACTION = new ForceMergeAction(1); private static final RolloverAction TEST_ROLLOVER_ACTION = new RolloverAction(new ByteSizeValue(1), null, null); private static final ShrinkAction TEST_SHRINK_ACTION = new ShrinkAction(1); @@ -556,6 +557,8 @@ private LifecycleAction getTestAction(String actionName) { switch (actionName) { case AllocateAction.NAME: return TEST_ALLOCATE_ACTION; + case WaitForSnapshotAction.NAME: + return TEST_WAIT_FOR_SNAPSHOT_ACTION; case DeleteAction.NAME: return TEST_DELETE_ACTION; case ForceMergeAction.NAME: From 0997fd10a296effadab836a5d4b8715f8497df07 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 01:31:37 +0100 Subject: [PATCH 12/25] Test fix --- .../org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java index 5470a6d31a586..0e59a569245e8 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java @@ -160,6 +160,8 @@ public static LifecyclePolicy randomTimeseriesLifecyclePolicy(@Nullable String l switch (action) { case AllocateAction.NAME: return AllocateActionTests.randomInstance(); + case WaitForSnapshotAction.NAME: + return new WaitForSnapshotAction("policy"); case DeleteAction.NAME: return new DeleteAction(); case ForceMergeAction.NAME: From 83feec222af78ddb2ce0ee6130717e434d97d37b Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 02:06:51 +0100 Subject: [PATCH 13/25] Test fix --- .../elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java index 2c8ac30f2a88c..d227f9498f7d4 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java @@ -36,6 +36,7 @@ import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType; import org.elasticsearch.xpack.core.ilm.UnfollowAction; +import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction; import java.io.IOException; import java.util.ArrayList; @@ -81,6 +82,7 @@ protected NamedWriteableRegistry getNamedWriteableRegistry() { new NamedWriteableRegistry.Entry(LifecycleType.class, TimeseriesLifecycleType.TYPE, (in) -> TimeseriesLifecycleType.INSTANCE), new NamedWriteableRegistry.Entry(LifecycleAction.class, AllocateAction.NAME, AllocateAction::new), + new NamedWriteableRegistry.Entry(LifecycleAction.class, WaitForSnapshotAction.NAME, WaitForSnapshotAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ForceMergeAction.NAME, ForceMergeAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new), @@ -100,6 +102,7 @@ protected NamedXContentRegistry xContentRegistry() { (p) -> TimeseriesLifecycleType.INSTANCE), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse), + new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse), From 0f24f07e4f7578cabf7595e85500fdc06ab6708e Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 02:14:48 +0100 Subject: [PATCH 14/25] Test fix --- .../elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java index d227f9498f7d4..dd8ea801cf06c 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleMetadataTests.java @@ -102,7 +102,8 @@ protected NamedXContentRegistry xContentRegistry() { (p) -> TimeseriesLifecycleType.INSTANCE), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse), - new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse), + new NamedXContentRegistry.Entry(LifecycleAction.class, + new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse), From b8976fce3079222463628737252c26341c41ca27 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 20:12:47 +0100 Subject: [PATCH 15/25] Test fix --- .../xpack/core/ilm/WaitForSnapshotStep.java | 12 ++++++++---- .../xpack/core/ilm/LifecyclePolicyMetadataTests.java | 3 +++ .../xpack/core/ilm/LifecyclePolicyTests.java | 3 +++ .../xpack/core/ilm/WaitForSnapshotStepTests.java | 8 ++++---- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java index 8fef7e18263cc..e02c0b7cfb9bb 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java @@ -22,7 +22,7 @@ public class WaitForSnapshotStep extends ClusterStateWaitStep { private static final String MESSAGE_FIELD = "message"; private static final String POLICY_NOT_EXECUTED_MESSAGE = "waiting for policy '%s' to be executed since %s"; - private static final String POLICY_NOT_FOUND_MESSAGE = "policy '%s' not found, waiting for it to be created and executed"; + private static final String POLICY_NOT_FOUND_MESSAGE = "configured policy '%s' not found"; private static final String NO_INDEX_METADATA_MESSAGE = "no index metadata found for index '%s'"; private static final String NO_PHASE_TIME_MESSAGE = "no information about ILM phase start in index metadata for index '%s'"; @@ -37,18 +37,18 @@ public class WaitForSnapshotStep extends ClusterStateWaitStep { public Result isConditionMet(Index index, ClusterState clusterState) { IndexMetaData indexMetaData = clusterState.metaData().index(index); if (indexMetaData == null) { - throw new IllegalStateException(String.format(Locale.ROOT, NO_INDEX_METADATA_MESSAGE, index.getName())); + throw error(NO_INDEX_METADATA_MESSAGE, index.getName()); } Long phaseTime = LifecycleExecutionState.fromIndexMetadata(indexMetaData).getPhaseTime(); if (phaseTime == null) { - throw new IllegalStateException(String.format(Locale.ROOT, NO_PHASE_TIME_MESSAGE, index.getName())); + throw error(NO_PHASE_TIME_MESSAGE, index.getName()); } SnapshotLifecycleMetadata snapMeta = clusterState.metaData().custom(SnapshotLifecycleMetadata.TYPE); if (snapMeta == null || snapMeta.getSnapshotConfigurations().containsKey(policy) == false) { - throw new IllegalStateException(POLICY_NOT_FOUND_MESSAGE); + throw error(POLICY_NOT_FOUND_MESSAGE, policy); } SnapshotLifecyclePolicyMetadata snapPolicyMeta = snapMeta.getSnapshotConfigurations().get(policy); if (snapPolicyMeta.getLastSuccess() == null || snapPolicyMeta.getLastSuccess().getTimestamp() < phaseTime) { @@ -76,6 +76,10 @@ private ToXContentObject notExecutedMessage(long time) { }; } + private IllegalStateException error(String message, Object... args) { + return new IllegalStateException(String.format(Locale.ROOT, message, args)); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyMetadataTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyMetadataTests.java index b21b59049a3f4..9b50616a128dd 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyMetadataTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyMetadataTests.java @@ -39,6 +39,7 @@ protected NamedWriteableRegistry getNamedWriteableRegistry() { new NamedWriteableRegistry.Entry(LifecycleType.class, TimeseriesLifecycleType.TYPE, (in) -> TimeseriesLifecycleType.INSTANCE), new NamedWriteableRegistry.Entry(LifecycleAction.class, AllocateAction.NAME, AllocateAction::new), + new NamedWriteableRegistry.Entry(LifecycleAction.class, WaitForSnapshotAction.NAME, WaitForSnapshotAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ForceMergeAction.NAME, ForceMergeAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new), @@ -57,6 +58,8 @@ protected NamedXContentRegistry xContentRegistry() { new NamedXContentRegistry.Entry(LifecycleType.class, new ParseField(TimeseriesLifecycleType.TYPE), (p) -> TimeseriesLifecycleType.INSTANCE), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse), + new NamedXContentRegistry.Entry(LifecycleAction.class, + new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse), diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java index 0e59a569245e8..72c38a4cf57fd 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java @@ -48,6 +48,7 @@ protected NamedWriteableRegistry getNamedWriteableRegistry() { new NamedWriteableRegistry.Entry(LifecycleType.class, TimeseriesLifecycleType.TYPE, (in) -> TimeseriesLifecycleType.INSTANCE), new NamedWriteableRegistry.Entry(LifecycleAction.class, AllocateAction.NAME, AllocateAction::new), + new NamedWriteableRegistry.Entry(LifecycleAction.class, WaitForSnapshotAction.NAME, WaitForSnapshotAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ForceMergeAction.NAME, ForceMergeAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new), @@ -66,6 +67,8 @@ protected NamedXContentRegistry xContentRegistry() { new NamedXContentRegistry.Entry(LifecycleType.class, new ParseField(TimeseriesLifecycleType.TYPE), (p) -> TimeseriesLifecycleType.INSTANCE), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse), + new NamedXContentRegistry.Entry(LifecycleAction.class, + new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse), diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java index 43bba6d670ef5..6c1822235ec97 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStepTests.java @@ -55,7 +55,7 @@ protected WaitForSnapshotStep copyInstance(WaitForSnapshotStep instance) { return new WaitForSnapshotStep(instance.getKey(), instance.getNextStepKey(), instance.getPolicy()); } - public void testNoSlmPolicies() throws IOException { + public void testNoSlmPolicies() { IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10)) .putCustom(LifecycleExecutionState.ILM_CUSTOM_METADATA_KEY, Map.of("phase_time", Long.toString(randomLong()))) .settings(settings(Version.CURRENT)) @@ -65,9 +65,9 @@ public void testNoSlmPolicies() throws IOException { MetaData.Builder meta = MetaData.builder().indices(indices.build()); ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(meta).build(); WaitForSnapshotStep instance = createRandomInstance(); - ClusterStateWaitStep.Result result = instance.isConditionMet(indexMetaData.getIndex(), clusterState); - assertFalse(result.isComplete()); - assertTrue(getMessage(result).contains("not found")); + IllegalStateException e = expectThrows(IllegalStateException.class, () -> instance.isConditionMet(indexMetaData.getIndex(), + clusterState)); + assertTrue(e.getMessage().contains(instance.getPolicy())); } public void testSlmPolicyNotExecuted() throws IOException { From 5f3a2cb40b227e30c56750ffedcd677fc9c862f7 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 21:51:35 +0100 Subject: [PATCH 16/25] Test fix --- .../elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java | 4 +++- .../xpack/core/ilm/WaitForSnapshotActionTests.java | 7 ++++++- .../xpack/core/ilm/action/PutLifecycleRequestTests.java | 4 ++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java index 72c38a4cf57fd..37b268c499dbb 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/LifecyclePolicyTests.java @@ -113,6 +113,8 @@ public static LifecyclePolicy randomTimeseriesLifecyclePolicyWithAllPhases(@Null return AllocateActionTests.randomInstance(); case DeleteAction.NAME: return new DeleteAction(); + case WaitForSnapshotAction.NAME: + return WaitForSnapshotActionTests.randomInstance(); case ForceMergeAction.NAME: return ForceMergeActionTests.randomInstance(); case ReadOnlyAction.NAME: @@ -164,7 +166,7 @@ public static LifecyclePolicy randomTimeseriesLifecyclePolicy(@Nullable String l case AllocateAction.NAME: return AllocateActionTests.randomInstance(); case WaitForSnapshotAction.NAME: - return new WaitForSnapshotAction("policy"); + return WaitForSnapshotActionTests.randomInstance(); case DeleteAction.NAME: return new DeleteAction(); case ForceMergeAction.NAME: diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java index bd74f9b1d2911..a35ac6b422dd6 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotActionTests.java @@ -36,7 +36,7 @@ protected WaitForSnapshotAction doParseInstance(XContentParser parser) throws IO @Override protected WaitForSnapshotAction createTestInstance() { - return new WaitForSnapshotAction(randomAlphaOfLengthBetween(5, 10)); + return randomInstance(); } @Override @@ -46,6 +46,11 @@ protected Writeable.Reader instanceReader() { @Override protected WaitForSnapshotAction mutateInstance(WaitForSnapshotAction instance) throws IOException { + return randomInstance(); + } + + static WaitForSnapshotAction randomInstance() { return new WaitForSnapshotAction(randomAlphaOfLengthBetween(5, 10)); } + } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/action/PutLifecycleRequestTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/action/PutLifecycleRequestTests.java index 137a81ba56f2d..f0fd2f7dd5d76 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/action/PutLifecycleRequestTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/action/PutLifecycleRequestTests.java @@ -26,6 +26,7 @@ import org.elasticsearch.xpack.core.ilm.ShrinkAction; import org.elasticsearch.xpack.core.ilm.TimeseriesLifecycleType; import org.elasticsearch.xpack.core.ilm.UnfollowAction; +import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction; import org.elasticsearch.xpack.core.ilm.action.PutLifecycleAction.Request; import org.junit.Before; @@ -64,6 +65,7 @@ protected NamedWriteableRegistry getNamedWriteableRegistry() { new NamedWriteableRegistry.Entry(LifecycleType.class, TimeseriesLifecycleType.TYPE, (in) -> TimeseriesLifecycleType.INSTANCE), new NamedWriteableRegistry.Entry(LifecycleAction.class, AllocateAction.NAME, AllocateAction::new), + new NamedWriteableRegistry.Entry(LifecycleAction.class, WaitForSnapshotAction.NAME, WaitForSnapshotAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ForceMergeAction.NAME, ForceMergeAction::new), new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new), @@ -82,6 +84,8 @@ protected NamedXContentRegistry xContentRegistry() { new NamedXContentRegistry.Entry(LifecycleType.class, new ParseField(TimeseriesLifecycleType.TYPE), (p) -> TimeseriesLifecycleType.INSTANCE), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(AllocateAction.NAME), AllocateAction::parse), + new NamedXContentRegistry.Entry(LifecycleAction.class, + new ParseField(WaitForSnapshotAction.NAME), WaitForSnapshotAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse), new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse), From 94d0cbdd5cfbb2a77dbf5a41978d2a20015ba2c2 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Fri, 3 Jan 2020 22:03:09 +0100 Subject: [PATCH 17/25] Javadoc --- .../elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java | 3 +++ .../elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java index cbd6edd4cb9ec..0b064edc5f6c2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java @@ -20,6 +20,9 @@ import java.util.List; import java.util.Objects; +/** + * A {@link LifecycleAction} which waits for snapshot to be taken (by configured SLM policy). + */ public class WaitForSnapshotAction implements LifecycleAction { public static final String NAME = "snapshot"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java index e02c0b7cfb9bb..2880de8ea3de5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotStep.java @@ -16,6 +16,11 @@ import java.util.Locale; import java.util.Objects; +/*** + * A step that waits for snapshot to be taken by SLM to ensure we have backup before we delete the index. + * It will signal error if it can't get data needed to do the check (phase time from ILM and SLM metadata) + * and will only return success if execution of SLM policy took place after index entered deleted phase. + */ public class WaitForSnapshotStep extends ClusterStateWaitStep { static final String NAME = "wait-for-snapshot"; From 0f5d0db3108bf45adc039e8cec9d84f19a76d69c Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 22:47:03 +0100 Subject: [PATCH 18/25] Docs added --- .../reference/ilm/policy-definitions.asciidoc | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/reference/ilm/policy-definitions.asciidoc b/docs/reference/ilm/policy-definitions.asciidoc index 7114516e4d2a9..cd3a84217d7a4 100644 --- a/docs/reference/ilm/policy-definitions.asciidoc +++ b/docs/reference/ilm/policy-definitions.asciidoc @@ -109,6 +109,7 @@ policy definition. - <> - <> * Delete + - <> - <> [[ilm-allocate-action]] @@ -220,6 +221,40 @@ PUT _ilm/policy/my_policy } -------------------------------------------------- +[[ilm-wait-for-snapshot-action]] +==== Wait For Snapshot + +Phases allowed: delete. + +The Wait For Snapshot Action waits for defined SLM policy to be executed to ensure that snapshot of index exists before +deletion. + +[[ilm-wait-for-snapshot-options]] +.Wait For Snapshot +[options="header"] +|====== +| Name | Required | Default | Description +| `policy` | yes | - | SLM policy name that this action should wait for +|====== + +[source,console] +-------------------------------------------------- +PUT _ilm/policy/my_policy +{ + "policy": { + "phases": { + "delete": { + "actions": { + "waitforsnapshot" : { + "policy": "slm-policy-name" + } + } + } + } + } +} +-------------------------------------------------- + [[ilm-delete-action]] ==== Delete From 1033a92bf490264b18397ec64ff98e5cf95efbdc Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 22:48:11 +0100 Subject: [PATCH 19/25] review comments --- .../ilm/TimeSeriesLifecycleActionsIT.java | 63 +++++++++---------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index 9a702fab6f5ac..ffe49968bac66 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -367,38 +367,6 @@ public void testWaitForSnapshotSlmExecutedBefore() throws Exception { assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("completed"))); } - private void createSlmPolicy() throws IOException { - Request request; - request = new Request("PUT", "/_slm/policy/slm"); - request.setJsonEntity(Strings - .toString(JsonXContent.contentBuilder() - .startObject() - .field("schedule", "59 59 23 31 12 ? 2099") - .field("repository", "repo") - .field("name", "snap" + randomAlphaOfLengthBetween(5, 10).toLowerCase(Locale.ROOT)) - .startObject("config") - .endObject() - .endObject())); - - assertOK(client().performRequest(request)); - } - - private void createSnapshotRepo() throws IOException { - Request request = new Request("PUT", "/_snapshot/repo"); - request.setJsonEntity(Strings - .toString(JsonXContent.contentBuilder() - .startObject() - .field("type", "fs") - .startObject("settings") - .field("compress", randomBoolean()) - .field("location", System.getProperty("tests.path.repo")) - .field("max_snapshot_bytes_per_sec", "256b") - .endObject() - .endObject())); - assertOK(client().performRequest(request)); - } - - public void testDelete() throws Exception { createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); @@ -1404,4 +1372,35 @@ private String getSnapshotState(String snapshot) throws IOException { assertThat(snapResponse.get("snapshot"), equalTo(snapshot)); return (String) snapResponse.get("state"); } + + private void createSlmPolicy() throws IOException { + Request request; + request = new Request("PUT", "/_slm/policy/slm"); + request.setJsonEntity(Strings + .toString(JsonXContent.contentBuilder() + .startObject() + .field("schedule", "59 59 23 31 12 ? 2099") + .field("repository", "repo") + .field("name", "snap" + randomAlphaOfLengthBetween(5, 10).toLowerCase(Locale.ROOT)) + .startObject("config") + .endObject() + .endObject())); + + assertOK(client().performRequest(request)); + } + + private void createSnapshotRepo() throws IOException { + Request request = new Request("PUT", "/_snapshot/repo"); + request.setJsonEntity(Strings + .toString(JsonXContent.contentBuilder() + .startObject() + .field("type", "fs") + .startObject("settings") + .field("compress", randomBoolean()) + .field("location", System.getProperty("tests.path.repo")) + .field("max_snapshot_bytes_per_sec", "256b") + .endObject() + .endObject())); + assertOK(client().performRequest(request)); + } } From 0d7e025101ccdad0421e4105be1aaa2ae5b8311d Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 22:51:31 +0100 Subject: [PATCH 20/25] action name changed --- .../xpack/core/ilm/AsyncWaitStep.java | 13 ++++++++++++- .../core/ilm/CloseFollowerIndexStep.java | 3 ++- .../xpack/core/ilm/DeleteStep.java | 2 +- .../xpack/core/ilm/FreezeStep.java | 2 +- .../xpack/core/ilm/OpenFollowerIndexStep.java | 3 ++- .../xpack/core/ilm/RolloverStep.java | 5 ++++- .../core/ilm/SetSingleNodeAllocateStep.java | 1 + .../xpack/core/ilm/ShrinkSetAliasStep.java | 1 + .../xpack/core/ilm/ShrinkStep.java | 3 ++- .../elasticsearch/xpack/core/ilm/Step.java | 19 ++++++++++++++++--- .../xpack/core/ilm/UpdateSettingsStep.java | 4 +++- .../core/ilm/WaitForRolloverReadyStep.java | 6 ++++-- .../xpack/core/ilm/WaitForSnapshotAction.java | 2 +- .../xpack/ilm/IndexLifecycleRunner.java | 2 +- 14 files changed, 51 insertions(+), 15 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java index 5c2071f8f76a1..c31c812d76a34 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java @@ -7,6 +7,7 @@ import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContentObject; /** @@ -28,7 +29,17 @@ protected Client getClient() { return client; } - public abstract void evaluateCondition(IndexMetaData indexMetaData, Listener listener); + public void evaluateCondition(Settings settings, IndexMetaData indexMetaData, Listener listener){ + evaluateCondition(indexMetaData, listener); + } + + public void evaluateCondition(IndexMetaData indexMetaData, Listener listener){ + try { + throw new UnsupportedOperationException(); + } catch (UnsupportedOperationException e) { + listener.onFailure(e); + } + } public interface Listener { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java index dbd7ba54d2212..8a3e9503f64fa 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java @@ -33,7 +33,8 @@ void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentCl } if (indexMetaData.getState() == IndexMetaData.State.OPEN) { - CloseIndexRequest closeIndexRequest = new CloseIndexRequest(followerIndex); + CloseIndexRequest closeIndexRequest = new CloseIndexRequest(followerIndex) + .masterNodeTimeout(getMasterTimeout(currentClusterState)); getClient().admin().indices().close(closeIndexRequest, ActionListener.wrap( r -> { assert r.isAcknowledged() : "close index response is not acknowledged"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java index c6a242a7410dc..c19f8f3ef7fc5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java @@ -24,7 +24,7 @@ public DeleteStep(StepKey key, StepKey nextStepKey, Client client) { @Override public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentState, Listener listener) { getClient().admin().indices() - .delete(new DeleteIndexRequest(indexMetaData.getIndex().getName()), + .delete(new DeleteIndexRequest(indexMetaData.getIndex().getName()).masterNodeTimeout(getMasterTimeout(currentState)), ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java index 32f4fc94ce97e..4b9c9a24d4caa 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java @@ -25,7 +25,7 @@ public FreezeStep(StepKey key, StepKey nextStepKey, Client client) { @Override public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentState, Listener listener) { getClient().admin().indices().execute(FreezeIndexAction.INSTANCE, - new FreezeRequest(indexMetaData.getIndex().getName()), + new FreezeRequest(indexMetaData.getIndex().getName()).masterNodeTimeout(getMasterTimeout(currentState)), ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java index 9883f83d02057..ea19d139407e4 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java @@ -24,7 +24,8 @@ final class OpenFollowerIndexStep extends AsyncActionStep { public void performAction(IndexMetaData indexMetaData, ClusterState currentClusterState, ClusterStateObserver observer, Listener listener) { if (indexMetaData.getState() == IndexMetaData.State.CLOSE) { - OpenIndexRequest request = new OpenIndexRequest(indexMetaData.getIndex().getName()); + OpenIndexRequest request = new OpenIndexRequest(indexMetaData.getIndex().getName()) + .masterNodeTimeout(getMasterTimeout(currentClusterState)); getClient().admin().indices().open(request, ActionListener.wrap( r -> { assert r.isAcknowledged() : "open index response is not acknowledged"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java index 90b9d15f21b85..4bfb0b003cdef 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java @@ -14,6 +14,8 @@ import org.elasticsearch.cluster.ClusterStateObserver; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.ClusterSettings; +import org.elasticsearch.common.unit.TimeValue; import java.util.Locale; import java.util.Objects; @@ -64,7 +66,8 @@ public void performAction(IndexMetaData indexMetaData, ClusterState currentClust } // Calling rollover with no conditions will always roll over the index - RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null); + RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null) + .masterNodeTimeout(getMasterTimeout(currentClusterState)); getClient().admin().indices().rolloverIndex(rolloverRequest, ActionListener.wrap(response -> { assert response.isRolledOver() : "the only way this rollover call should fail is with an exception"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java index 5ce80823e9312..9bd3a70c5894a 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java @@ -83,6 +83,7 @@ public void performAction(IndexMetaData indexMetaData, ClusterState clusterState Settings settings = Settings.builder() .put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "_id", nodeId.get()).build(); UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetaData.getIndex().getName()) + .masterNodeTimeout(getMasterTimeout(clusterState)) .settings(settings); getClient().admin().indices().updateSettings(updateSettingsRequest, ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java index 78426c5b336f1..b9fc51f89cff9 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java @@ -38,6 +38,7 @@ public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState cu // get target shrink index String targetIndexName = shrunkIndexPrefix + index; IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest() + .masterNodeTimeout(getMasterTimeout(currentState)) .addAliasAction(IndicesAliasesRequest.AliasActions.removeIndex().index(index)) .addAliasAction(IndicesAliasesRequest.AliasActions.add().index(targetIndexName).alias(index)); // copy over other aliases from original index 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 index 2bddfe6771317..fb15ea6d9adff 100644 --- 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 @@ -57,7 +57,8 @@ public void performAction(IndexMetaData indexMetaData, ClusterState currentState .build(); String shrunkenIndexName = shrunkIndexPrefix + indexMetaData.getIndex().getName(); - ResizeRequest resizeRequest = new ResizeRequest(shrunkenIndexName, indexMetaData.getIndex().getName()); + ResizeRequest resizeRequest = new ResizeRequest(shrunkenIndexName, indexMetaData.getIndex().getName()) + .masterNodeTimeout(getMasterTimeout(currentState)); resizeRequest.getTargetIndexRequest().settings(relevantTargetSettings); getClient().admin().indices().resizeIndex(resizeRequest, ActionListener.wrap(response -> { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java index 7356765acd9e6..108d0b558e1b5 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java @@ -5,11 +5,14 @@ */ package org.elasticsearch.xpack.core.ilm; +import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.settings.Setting; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -22,6 +25,11 @@ * Represents one part of the execution of a {@link LifecycleAction}. */ public abstract class Step { + + private static final String ILM_STEP_MASTER_TIMEOUT = "ilm.step.master.timeout"; + protected static final Setting ILM_STEP_MASTER_TIMEOUT_SETTING = Setting.positiveTimeSetting(ILM_STEP_MASTER_TIMEOUT, + TimeValue.timeValueSeconds(30), Setting.Property.Dynamic, Setting.Property.NodeScope); + private final StepKey key; private final StepKey nextStepKey; @@ -60,7 +68,7 @@ public boolean equals(Object obj) { } Step other = (Step) obj; return Objects.equals(key, other.key) && - Objects.equals(nextStepKey, other.nextStepKey); + Objects.equals(nextStepKey, other.nextStepKey); } @Override @@ -68,6 +76,10 @@ public String toString() { return key + " => " + nextStepKey; } + protected TimeValue getMasterTimeout(ClusterState clusterState){ + return ILM_STEP_MASTER_TIMEOUT_SETTING.get(clusterState.metaData().settings()); + } + public static final class StepKey implements Writeable, ToXContentObject { private final String phase; private final String action; @@ -78,6 +90,7 @@ public static final class StepKey implements Writeable, ToXContentObject { public static final ParseField NAME_FIELD = new ParseField("name"); private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("stepkey", a -> new StepKey((String) a[0], (String) a[1], (String) a[2])); + static { PARSER.declareString(ConstructingObjectParser.constructorArg(), PHASE_FIELD); PARSER.declareString(ConstructingObjectParser.constructorArg(), ACTION_FIELD); @@ -134,8 +147,8 @@ public boolean equals(Object obj) { } StepKey other = (StepKey) obj; return Objects.equals(phase, other.phase) && - Objects.equals(action, other.action) && - Objects.equals(name, other.name); + Objects.equals(action, other.action) && + Objects.equals(name, other.name); } @Override diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java index 41d49f1fbd417..4b5797dbe034b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java @@ -30,7 +30,9 @@ public UpdateSettingsStep(StepKey key, StepKey nextStepKey, Client client, Setti @Override public void performAction(IndexMetaData indexMetaData, ClusterState currentState, ClusterStateObserver observer, Listener listener) { - UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetaData.getIndex().getName()).settings(settings); + UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetaData.getIndex().getName()) + .masterNodeTimeout(getMasterTimeout(currentState)) + .settings(settings); getClient().admin().indices().updateSettings(updateSettingsRequest, ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java index 8cbf64d1d392f..8edcf6c655aaf 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java @@ -13,6 +13,7 @@ import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContentObject; @@ -48,7 +49,7 @@ public boolean isRetryable() { } @Override - public void evaluateCondition(IndexMetaData indexMetaData, Listener listener) { + public void evaluateCondition(Settings settings, IndexMetaData indexMetaData, Listener listener) { String rolloverAlias = RolloverAction.LIFECYCLE_ROLLOVER_ALIAS_SETTING.get(indexMetaData.getSettings()); if (Strings.isNullOrEmpty(rolloverAlias)) { @@ -113,7 +114,8 @@ public void evaluateCondition(IndexMetaData indexMetaData, Listener listener) { "index [%s] is not the write index for alias [%s]", indexMetaData.getIndex().getName(), rolloverAlias))); } - RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null); + RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null) + .masterNodeTimeout(ILM_STEP_MASTER_TIMEOUT_SETTING.get(settings)); rolloverRequest.dryRun(true); if (maxAge != null) { rolloverRequest.addMaxIndexAgeCondition(maxAge); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java index 0b064edc5f6c2..91959ed233974 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java @@ -25,7 +25,7 @@ */ public class WaitForSnapshotAction implements LifecycleAction { - public static final String NAME = "snapshot"; + public static final String NAME = "waitforsnapshot"; public static final ParseField POLICY_FIELD = new ParseField("policy"); private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java index 736d5decc1123..2f3b905fecd50 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java @@ -149,7 +149,7 @@ void runPeriodicStep(String policy, IndexMetaData indexMetaData) { } } else if (currentStep instanceof AsyncWaitStep) { logger.debug("[{}] running periodic policy with current-step [{}]", index, currentStep.getKey()); - ((AsyncWaitStep) currentStep).evaluateCondition(indexMetaData, new AsyncWaitStep.Listener() { + ((AsyncWaitStep) currentStep).evaluateCondition(clusterService.getSettings(), indexMetaData, new AsyncWaitStep.Listener() { @Override public void onResponse(boolean conditionMet, ToXContentObject stepInfo) { From 2c2794ccfe97873773df0d53752e143f6f1d2048 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 22:52:33 +0100 Subject: [PATCH 21/25] Revert "action name changed" This reverts commit 0d7e025101ccdad0421e4105be1aaa2ae5b8311d. --- .../xpack/core/ilm/AsyncWaitStep.java | 13 +------------ .../core/ilm/CloseFollowerIndexStep.java | 3 +-- .../xpack/core/ilm/DeleteStep.java | 2 +- .../xpack/core/ilm/FreezeStep.java | 2 +- .../xpack/core/ilm/OpenFollowerIndexStep.java | 3 +-- .../xpack/core/ilm/RolloverStep.java | 5 +---- .../core/ilm/SetSingleNodeAllocateStep.java | 1 - .../xpack/core/ilm/ShrinkSetAliasStep.java | 1 - .../xpack/core/ilm/ShrinkStep.java | 3 +-- .../elasticsearch/xpack/core/ilm/Step.java | 19 +++---------------- .../xpack/core/ilm/UpdateSettingsStep.java | 4 +--- .../core/ilm/WaitForRolloverReadyStep.java | 6 ++---- .../xpack/core/ilm/WaitForSnapshotAction.java | 2 +- .../xpack/ilm/IndexLifecycleRunner.java | 2 +- 14 files changed, 15 insertions(+), 51 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java index c31c812d76a34..5c2071f8f76a1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/AsyncWaitStep.java @@ -7,7 +7,6 @@ import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContentObject; /** @@ -29,17 +28,7 @@ protected Client getClient() { return client; } - public void evaluateCondition(Settings settings, IndexMetaData indexMetaData, Listener listener){ - evaluateCondition(indexMetaData, listener); - } - - public void evaluateCondition(IndexMetaData indexMetaData, Listener listener){ - try { - throw new UnsupportedOperationException(); - } catch (UnsupportedOperationException e) { - listener.onFailure(e); - } - } + public abstract void evaluateCondition(IndexMetaData indexMetaData, Listener listener); public interface Listener { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java index 8a3e9503f64fa..dbd7ba54d2212 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CloseFollowerIndexStep.java @@ -33,8 +33,7 @@ void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentCl } if (indexMetaData.getState() == IndexMetaData.State.OPEN) { - CloseIndexRequest closeIndexRequest = new CloseIndexRequest(followerIndex) - .masterNodeTimeout(getMasterTimeout(currentClusterState)); + CloseIndexRequest closeIndexRequest = new CloseIndexRequest(followerIndex); getClient().admin().indices().close(closeIndexRequest, ActionListener.wrap( r -> { assert r.isAcknowledged() : "close index response is not acknowledged"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java index c19f8f3ef7fc5..c6a242a7410dc 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/DeleteStep.java @@ -24,7 +24,7 @@ public DeleteStep(StepKey key, StepKey nextStepKey, Client client) { @Override public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentState, Listener listener) { getClient().admin().indices() - .delete(new DeleteIndexRequest(indexMetaData.getIndex().getName()).masterNodeTimeout(getMasterTimeout(currentState)), + .delete(new DeleteIndexRequest(indexMetaData.getIndex().getName()), ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java index 4b9c9a24d4caa..32f4fc94ce97e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/FreezeStep.java @@ -25,7 +25,7 @@ public FreezeStep(StepKey key, StepKey nextStepKey, Client client) { @Override public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState currentState, Listener listener) { getClient().admin().indices().execute(FreezeIndexAction.INSTANCE, - new FreezeRequest(indexMetaData.getIndex().getName()).masterNodeTimeout(getMasterTimeout(currentState)), + new FreezeRequest(indexMetaData.getIndex().getName()), ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java index ea19d139407e4..9883f83d02057 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/OpenFollowerIndexStep.java @@ -24,8 +24,7 @@ final class OpenFollowerIndexStep extends AsyncActionStep { public void performAction(IndexMetaData indexMetaData, ClusterState currentClusterState, ClusterStateObserver observer, Listener listener) { if (indexMetaData.getState() == IndexMetaData.State.CLOSE) { - OpenIndexRequest request = new OpenIndexRequest(indexMetaData.getIndex().getName()) - .masterNodeTimeout(getMasterTimeout(currentClusterState)); + OpenIndexRequest request = new OpenIndexRequest(indexMetaData.getIndex().getName()); getClient().admin().indices().open(request, ActionListener.wrap( r -> { assert r.isAcknowledged() : "open index response is not acknowledged"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java index 4bfb0b003cdef..90b9d15f21b85 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/RolloverStep.java @@ -14,8 +14,6 @@ import org.elasticsearch.cluster.ClusterStateObserver; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.ClusterSettings; -import org.elasticsearch.common.unit.TimeValue; import java.util.Locale; import java.util.Objects; @@ -66,8 +64,7 @@ public void performAction(IndexMetaData indexMetaData, ClusterState currentClust } // Calling rollover with no conditions will always roll over the index - RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null) - .masterNodeTimeout(getMasterTimeout(currentClusterState)); + RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null); getClient().admin().indices().rolloverIndex(rolloverRequest, ActionListener.wrap(response -> { assert response.isRolledOver() : "the only way this rollover call should fail is with an exception"; diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java index 9bd3a70c5894a..5ce80823e9312 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/SetSingleNodeAllocateStep.java @@ -83,7 +83,6 @@ public void performAction(IndexMetaData indexMetaData, ClusterState clusterState Settings settings = Settings.builder() .put(IndexMetaData.INDEX_ROUTING_REQUIRE_GROUP_SETTING.getKey() + "_id", nodeId.get()).build(); UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetaData.getIndex().getName()) - .masterNodeTimeout(getMasterTimeout(clusterState)) .settings(settings); getClient().admin().indices().updateSettings(updateSettingsRequest, ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java index b9fc51f89cff9..78426c5b336f1 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/ShrinkSetAliasStep.java @@ -38,7 +38,6 @@ public void performDuringNoSnapshot(IndexMetaData indexMetaData, ClusterState cu // get target shrink index String targetIndexName = shrunkIndexPrefix + index; IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest() - .masterNodeTimeout(getMasterTimeout(currentState)) .addAliasAction(IndicesAliasesRequest.AliasActions.removeIndex().index(index)) .addAliasAction(IndicesAliasesRequest.AliasActions.add().index(targetIndexName).alias(index)); // copy over other aliases from original index 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 index fb15ea6d9adff..2bddfe6771317 100644 --- 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 @@ -57,8 +57,7 @@ public void performAction(IndexMetaData indexMetaData, ClusterState currentState .build(); String shrunkenIndexName = shrunkIndexPrefix + indexMetaData.getIndex().getName(); - ResizeRequest resizeRequest = new ResizeRequest(shrunkenIndexName, indexMetaData.getIndex().getName()) - .masterNodeTimeout(getMasterTimeout(currentState)); + ResizeRequest resizeRequest = new ResizeRequest(shrunkenIndexName, indexMetaData.getIndex().getName()); resizeRequest.getTargetIndexRequest().settings(relevantTargetSettings); getClient().admin().indices().resizeIndex(resizeRequest, ActionListener.wrap(response -> { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java index 108d0b558e1b5..7356765acd9e6 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/Step.java @@ -5,14 +5,11 @@ */ package org.elasticsearch.xpack.core.ilm; -import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -25,11 +22,6 @@ * Represents one part of the execution of a {@link LifecycleAction}. */ public abstract class Step { - - private static final String ILM_STEP_MASTER_TIMEOUT = "ilm.step.master.timeout"; - protected static final Setting ILM_STEP_MASTER_TIMEOUT_SETTING = Setting.positiveTimeSetting(ILM_STEP_MASTER_TIMEOUT, - TimeValue.timeValueSeconds(30), Setting.Property.Dynamic, Setting.Property.NodeScope); - private final StepKey key; private final StepKey nextStepKey; @@ -68,7 +60,7 @@ public boolean equals(Object obj) { } Step other = (Step) obj; return Objects.equals(key, other.key) && - Objects.equals(nextStepKey, other.nextStepKey); + Objects.equals(nextStepKey, other.nextStepKey); } @Override @@ -76,10 +68,6 @@ public String toString() { return key + " => " + nextStepKey; } - protected TimeValue getMasterTimeout(ClusterState clusterState){ - return ILM_STEP_MASTER_TIMEOUT_SETTING.get(clusterState.metaData().settings()); - } - public static final class StepKey implements Writeable, ToXContentObject { private final String phase; private final String action; @@ -90,7 +78,6 @@ public static final class StepKey implements Writeable, ToXContentObject { public static final ParseField NAME_FIELD = new ParseField("name"); private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("stepkey", a -> new StepKey((String) a[0], (String) a[1], (String) a[2])); - static { PARSER.declareString(ConstructingObjectParser.constructorArg(), PHASE_FIELD); PARSER.declareString(ConstructingObjectParser.constructorArg(), ACTION_FIELD); @@ -147,8 +134,8 @@ public boolean equals(Object obj) { } StepKey other = (StepKey) obj; return Objects.equals(phase, other.phase) && - Objects.equals(action, other.action) && - Objects.equals(name, other.name); + Objects.equals(action, other.action) && + Objects.equals(name, other.name); } @Override diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java index 4b5797dbe034b..41d49f1fbd417 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/UpdateSettingsStep.java @@ -30,9 +30,7 @@ public UpdateSettingsStep(StepKey key, StepKey nextStepKey, Client client, Setti @Override public void performAction(IndexMetaData indexMetaData, ClusterState currentState, ClusterStateObserver observer, Listener listener) { - UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetaData.getIndex().getName()) - .masterNodeTimeout(getMasterTimeout(currentState)) - .settings(settings); + UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetaData.getIndex().getName()).settings(settings); getClient().admin().indices().updateSettings(updateSettingsRequest, ActionListener.wrap(response -> listener.onResponse(true), listener::onFailure)); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java index 8edcf6c655aaf..8cbf64d1d392f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForRolloverReadyStep.java @@ -13,7 +13,6 @@ import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.Strings; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContentObject; @@ -49,7 +48,7 @@ public boolean isRetryable() { } @Override - public void evaluateCondition(Settings settings, IndexMetaData indexMetaData, Listener listener) { + public void evaluateCondition(IndexMetaData indexMetaData, Listener listener) { String rolloverAlias = RolloverAction.LIFECYCLE_ROLLOVER_ALIAS_SETTING.get(indexMetaData.getSettings()); if (Strings.isNullOrEmpty(rolloverAlias)) { @@ -114,8 +113,7 @@ public void evaluateCondition(Settings settings, IndexMetaData indexMetaData, Li "index [%s] is not the write index for alias [%s]", indexMetaData.getIndex().getName(), rolloverAlias))); } - RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null) - .masterNodeTimeout(ILM_STEP_MASTER_TIMEOUT_SETTING.get(settings)); + RolloverRequest rolloverRequest = new RolloverRequest(rolloverAlias, null); rolloverRequest.dryRun(true); if (maxAge != null) { rolloverRequest.addMaxIndexAgeCondition(maxAge); diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java index 91959ed233974..0b064edc5f6c2 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java @@ -25,7 +25,7 @@ */ public class WaitForSnapshotAction implements LifecycleAction { - public static final String NAME = "waitforsnapshot"; + public static final String NAME = "snapshot"; public static final ParseField POLICY_FIELD = new ParseField("policy"); private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java index 2f3b905fecd50..736d5decc1123 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleRunner.java @@ -149,7 +149,7 @@ void runPeriodicStep(String policy, IndexMetaData indexMetaData) { } } else if (currentStep instanceof AsyncWaitStep) { logger.debug("[{}] running periodic policy with current-step [{}]", index, currentStep.getKey()); - ((AsyncWaitStep) currentStep).evaluateCondition(clusterService.getSettings(), indexMetaData, new AsyncWaitStep.Listener() { + ((AsyncWaitStep) currentStep).evaluateCondition(indexMetaData, new AsyncWaitStep.Listener() { @Override public void onResponse(boolean conditionMet, ToXContentObject stepInfo) { From bea77f202a94970c84163fd35a12111ae3818e66 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 22:53:05 +0100 Subject: [PATCH 22/25] action name changed --- .../org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java index 0b064edc5f6c2..91959ed233974 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java @@ -25,7 +25,7 @@ */ public class WaitForSnapshotAction implements LifecycleAction { - public static final String NAME = "snapshot"; + public static final String NAME = "waitforsnapshot"; public static final ParseField POLICY_FIELD = new ParseField("policy"); private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, From 015a940bef74763141aaedf3e9382c0a4c2d37a4 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 23:10:14 +0100 Subject: [PATCH 23/25] action name changed --- .../org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java index 91959ed233974..566b54b470c6d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/WaitForSnapshotAction.java @@ -25,7 +25,7 @@ */ public class WaitForSnapshotAction implements LifecycleAction { - public static final String NAME = "waitforsnapshot"; + public static final String NAME = "wait_for_snapshot"; public static final ParseField POLICY_FIELD = new ParseField("policy"); private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(NAME, From 704dd626767dbf7a3a54bb6383d660f1c7cc5847 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Wed, 8 Jan 2020 23:16:02 +0100 Subject: [PATCH 24/25] Action name updated in docs Co-Authored-By: Lee Hinman --- docs/reference/ilm/policy-definitions.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/ilm/policy-definitions.asciidoc b/docs/reference/ilm/policy-definitions.asciidoc index cd3a84217d7a4..65401a5c866d7 100644 --- a/docs/reference/ilm/policy-definitions.asciidoc +++ b/docs/reference/ilm/policy-definitions.asciidoc @@ -245,7 +245,7 @@ PUT _ilm/policy/my_policy "phases": { "delete": { "actions": { - "waitforsnapshot" : { + "wait_for_snapshot" : { "policy": "slm-policy-name" } } From 440ba8031d1099de82457af2c3f72d1dc476f288 Mon Sep 17 00:00:00 2001 From: Przemko Robakowski Date: Thu, 9 Jan 2020 00:42:06 +0100 Subject: [PATCH 25/25] test fix --- .../xpack/ilm/TimeSeriesLifecycleActionsIT.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java index b4afcb2da78dd..e41c9baf93ec5 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/ilm/TimeSeriesLifecycleActionsIT.java @@ -329,14 +329,14 @@ public void testWaitForSnapshot() throws Exception { .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); createNewSingletonPolicy("delete", new WaitForSnapshotAction("slm")); updatePolicy(index, policy); - assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("wait_for_snapshot"))); assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); assertBusy(() -> assertThat(getFailedStepForIndex(index), equalTo("wait-for-snapshot"))); createSnapshotRepo(); createSlmPolicy(); - assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("wait_for_snapshot"))); Request request = new Request("PUT", "/_slm/policy/slm/_execute"); assertOK(client().performRequest(request)); @@ -356,11 +356,9 @@ public void testWaitForSnapshotSlmExecutedBefore() throws Exception { assertOK(client().performRequest(request)); updatePolicy(index, policy); - assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); + assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("wait_for_snapshot"))); assertBusy(() -> assertThat(getStepKeyForIndex(index).getName(), equalTo("wait-for-snapshot"))); - - assertBusy(() -> assertThat(getStepKeyForIndex(index).getAction(), equalTo("snapshot"))); - + request = new Request("PUT", "/_slm/policy/slm/_execute"); assertOK(client().performRequest(request));