HLRC: add support for the wait_for_snapshot ILM action (#62333) (#62931)

(cherry picked from commit b8a10b3995669954f0e8c6b3512c50da6c76d48d)
Signed-off-by: Andrei Dan <andrei.dan@elastic.co>
This commit is contained in:
Andrei Dan 2020-09-28 09:54:24 +01:00 committed by GitHub
parent b1a8437d0b
commit 25106ba58f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 167 additions and 5 deletions

View File

@ -51,6 +51,9 @@ public class IndexLifecycleNamedXContentProvider implements NamedXContentProvide
new NamedXContentRegistry.Entry(LifecycleAction.class,
new ParseField(ShrinkAction.NAME),
ShrinkAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class,
new ParseField(WaitForSnapshotAction.NAME),
WaitForSnapshotAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class,
new ParseField(FreezeAction.NAME),
FreezeAction::parse),

View File

@ -62,7 +62,7 @@ public class LifecyclePolicy implements ToXContentObject {
ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME));
ALLOWED_ACTIONS.put("cold", Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, MigrateAction.NAME, AllocateAction.NAME,
FreezeAction.NAME, SearchableSnapshotAction.NAME));
ALLOWED_ACTIONS.put("delete", Sets.newHashSet(DeleteAction.NAME));
ALLOWED_ACTIONS.put("delete", Sets.newHashSet(DeleteAction.NAME, WaitForSnapshotAction.NAME));
}
private final String name;

View File

@ -0,0 +1,86 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client.indexlifecycle;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
/**
* A {@link LifecycleAction} which waits for snapshot to be taken (by configured SLM policy).
*/
public class WaitForSnapshotAction implements LifecycleAction, ToXContentObject {
public static final String NAME = "wait_for_snapshot";
public static final ParseField POLICY_FIELD = new ParseField("policy");
private static final ConstructingObjectParser<WaitForSnapshotAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
true, a -> new WaitForSnapshotAction((String) a[0]));
static {
PARSER.declareString(ConstructingObjectParser.constructorArg(), POLICY_FIELD);
}
private final String policy;
public static WaitForSnapshotAction parse(XContentParser parser) {
return PARSER.apply(parser, null);
}
public WaitForSnapshotAction(String policy) {
if (Strings.hasText(policy) == false) {
throw new IllegalArgumentException("policy name must be specified");
}
this.policy = policy;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.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;
WaitForSnapshotAction that = (WaitForSnapshotAction) o;
return policy.equals(that.policy);
}
@Override
public int hashCode() {
return Objects.hash(policy);
}
@Override
public String getName() {
return NAME;
}
}

View File

@ -50,6 +50,7 @@ import org.elasticsearch.client.indexlifecycle.ShrinkAction;
import org.elasticsearch.client.indexlifecycle.StartILMRequest;
import org.elasticsearch.client.indexlifecycle.StopILMRequest;
import org.elasticsearch.client.indexlifecycle.UnfollowAction;
import org.elasticsearch.client.indexlifecycle.WaitForSnapshotAction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.hamcrest.Matchers;
@ -164,7 +165,9 @@ public class IndexLifecycleIT extends ESRestHighLevelClientTestCase {
coldActions.put(SearchableSnapshotAction.NAME, new SearchableSnapshotAction("repo"));
lifecyclePhases.put("cold", new Phase("cold", TimeValue.timeValueSeconds(2000), coldActions));
Map<String, LifecycleAction> deleteActions = Collections.singletonMap(DeleteAction.NAME, new DeleteAction());
Map<String, LifecycleAction> deleteActions = new HashMap<>();
deleteActions.put(WaitForSnapshotAction.NAME, new WaitForSnapshotAction("policy"));
deleteActions.put(DeleteAction.NAME, new DeleteAction());
lifecyclePhases.put("delete", new Phase("delete", TimeValue.timeValueSeconds(3000), deleteActions));
LifecyclePolicy policy = new LifecyclePolicy(randomAlphaOfLength(10), lifecyclePhases);

View File

@ -56,6 +56,7 @@ import org.elasticsearch.client.indexlifecycle.SearchableSnapshotAction;
import org.elasticsearch.client.indexlifecycle.SetPriorityAction;
import org.elasticsearch.client.indexlifecycle.ShrinkAction;
import org.elasticsearch.client.indexlifecycle.UnfollowAction;
import org.elasticsearch.client.indexlifecycle.WaitForSnapshotAction;
import org.elasticsearch.client.ml.dataframe.DataFrameAnalysis;
import org.elasticsearch.client.ml.dataframe.evaluation.classification.AccuracyMetric;
import org.elasticsearch.client.ml.dataframe.evaluation.classification.Classification;
@ -706,7 +707,7 @@ public class RestHighLevelClientTests extends ESTestCase {
public void testProvidedNamedXContents() {
List<NamedXContentRegistry.Entry> namedXContents = RestHighLevelClient.getProvidedNamedXContents();
assertEquals(72, namedXContents.size());
assertEquals(73, namedXContents.size());
Map<Class<?>, Integer> categories = new HashMap<>();
List<String> names = new ArrayList<>();
for (NamedXContentRegistry.Entry namedXContent : namedXContents) {
@ -732,13 +733,14 @@ public class RestHighLevelClientTests extends ESTestCase {
assertTrue(names.contains(MeanReciprocalRank.NAME));
assertTrue(names.contains(DiscountedCumulativeGain.NAME));
assertTrue(names.contains(ExpectedReciprocalRank.NAME));
assertEquals(Integer.valueOf(11), categories.get(LifecycleAction.class));
assertEquals(Integer.valueOf(12), categories.get(LifecycleAction.class));
assertTrue(names.contains(UnfollowAction.NAME));
assertTrue(names.contains(AllocateAction.NAME));
assertTrue(names.contains(DeleteAction.NAME));
assertTrue(names.contains(ForceMergeAction.NAME));
assertTrue(names.contains(ReadOnlyAction.NAME));
assertTrue(names.contains(RolloverAction.NAME));
assertTrue(names.contains(WaitForSnapshotAction.NAME));
assertTrue(names.contains(ShrinkAction.NAME));
assertTrue(names.contains(FreezeAction.NAME));
assertTrue(names.contains(SetPriorityAction.NAME));

View File

@ -85,6 +85,8 @@ public class GetLifecyclePolicyResponseTests extends AbstractXContentTestCase<Ge
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(WaitForSnapshotAction.NAME),
WaitForSnapshotAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SetPriorityAction.NAME), SetPriorityAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(SearchableSnapshotAction.NAME),
SearchableSnapshotAction::parse),

View File

@ -78,6 +78,8 @@ public class LifecyclePolicyMetadataTests extends AbstractXContentTestCase<Lifec
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(WaitForSnapshotAction.NAME),
WaitForSnapshotAction::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(SearchableSnapshotAction.NAME),

View File

@ -45,7 +45,7 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME);
private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(UnfollowAction.NAME, SetPriorityAction.NAME, AllocateAction.NAME,
FreezeAction.NAME, SearchableSnapshotAction.NAME);
private static final Set<String> VALID_DELETE_ACTIONS = Sets.newHashSet(DeleteAction.NAME);
private static final Set<String> VALID_DELETE_ACTIONS = Sets.newHashSet(DeleteAction.NAME, WaitForSnapshotAction.NAME);
private String lifecycleName;
@ -75,6 +75,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(WaitForSnapshotAction.NAME),
WaitForSnapshotAction::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(SearchableSnapshotAction.NAME),
@ -222,6 +224,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
return ShrinkActionTests.randomInstance();
case FreezeAction.NAME:
return new FreezeAction();
case WaitForSnapshotAction.NAME:
return WaitForSnapshotActionTests.randomInstance();
case SetPriorityAction.NAME:
return SetPriorityActionTests.randomInstance();
case UnfollowAction.NAME:
@ -259,6 +263,8 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
return ShrinkActionTests.randomInstance();
case FreezeAction.NAME:
return new FreezeAction();
case WaitForSnapshotAction.NAME:
return WaitForSnapshotActionTests.randomInstance();
case SetPriorityAction.NAME:
return SetPriorityActionTests.randomInstance();
case SearchableSnapshotAction.NAME:

View File

@ -0,0 +1,58 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.client.indexlifecycle;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractXContentTestCase;
import static org.hamcrest.Matchers.is;
public class WaitForSnapshotActionTests extends AbstractXContentTestCase<WaitForSnapshotAction> {
@Override
protected WaitForSnapshotAction doParseInstance(XContentParser parser) {
return WaitForSnapshotAction.parse(parser);
}
@Override
protected boolean supportsUnknownFields() {
return true;
}
static WaitForSnapshotAction randomInstance() {
return new WaitForSnapshotAction(randomAlphaOfLength(5));
}
@Override
protected WaitForSnapshotAction createTestInstance() {
return randomInstance();
}
public void testActionWithEmptyOrNullPolicy() {
{
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> new WaitForSnapshotAction(""));
assertThat(exception.getMessage(), is("policy name must be specified"));
}
{
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> new WaitForSnapshotAction(null));
assertThat(exception.getMessage(), is("policy name must be specified"));
}
}
}