Skip to content

Commit 608f234

Browse files
committed
[ILM] Add Freeze Action (#36910)
This commit adds a new ILM Action for freezing indices in the cold phase. Closes #34630.
1 parent c3c6ebb commit 608f234

File tree

22 files changed

+542
-22
lines changed

22 files changed

+542
-22
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client.indexlifecycle;
20+
21+
import org.elasticsearch.common.Strings;
22+
import org.elasticsearch.common.xcontent.ObjectParser;
23+
import org.elasticsearch.common.xcontent.ToXContentObject;
24+
import org.elasticsearch.common.xcontent.XContentBuilder;
25+
import org.elasticsearch.common.xcontent.XContentParser;
26+
27+
import java.io.IOException;
28+
29+
public class FreezeAction implements LifecycleAction, ToXContentObject {
30+
public static final String NAME = "freeze";
31+
32+
private static final ObjectParser<FreezeAction, Void> PARSER = new ObjectParser<>(NAME, FreezeAction::new);
33+
34+
public static FreezeAction parse(XContentParser parser) {
35+
return PARSER.apply(parser, null);
36+
}
37+
38+
public FreezeAction() {
39+
}
40+
41+
@Override
42+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
43+
builder.startObject();
44+
builder.endObject();
45+
return builder;
46+
}
47+
48+
@Override
49+
public String getName() {
50+
return NAME;
51+
}
52+
53+
@Override
54+
public int hashCode() {
55+
return 1;
56+
}
57+
58+
@Override
59+
public boolean equals(Object obj) {
60+
if (obj == null) {
61+
return false;
62+
}
63+
if (obj.getClass() != getClass()) {
64+
return false;
65+
}
66+
return true;
67+
}
68+
69+
@Override
70+
public String toString() {
71+
return Strings.toString(this);
72+
}
73+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/indexlifecycle/IndexLifecycleNamedXContentProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ public List<NamedXContentRegistry.Entry> getNamedXContentParsers() {
5050
RolloverAction::parse),
5151
new NamedXContentRegistry.Entry(LifecycleAction.class,
5252
new ParseField(ShrinkAction.NAME),
53-
ShrinkAction::parse)
53+
ShrinkAction::parse),
54+
new NamedXContentRegistry.Entry(LifecycleAction.class,
55+
new ParseField(FreezeAction.NAME),
56+
FreezeAction::parse)
5457
);
5558
}
5659
}

client/rest-high-level/src/main/java/org/elasticsearch/client/indexlifecycle/LifecyclePolicy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public class LifecyclePolicy implements ToXContentObject {
5959

6060
ALLOWED_ACTIONS.put("hot", Sets.newHashSet(RolloverAction.NAME));
6161
ALLOWED_ACTIONS.put("warm", Sets.newHashSet(AllocateAction.NAME, ForceMergeAction.NAME, ReadOnlyAction.NAME, ShrinkAction.NAME));
62-
ALLOWED_ACTIONS.put("cold", Sets.newHashSet(AllocateAction.NAME));
62+
ALLOWED_ACTIONS.put("cold", Sets.newHashSet(AllocateAction.NAME, FreezeAction.NAME));
6363
ALLOWED_ACTIONS.put("delete", Sets.newHashSet(DeleteAction.NAME));
6464
}
6565

client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.elasticsearch.client.indexlifecycle.AllocateAction;
5353
import org.elasticsearch.client.indexlifecycle.DeleteAction;
5454
import org.elasticsearch.client.indexlifecycle.ForceMergeAction;
55+
import org.elasticsearch.client.indexlifecycle.FreezeAction;
5556
import org.elasticsearch.client.indexlifecycle.LifecycleAction;
5657
import org.elasticsearch.client.indexlifecycle.ReadOnlyAction;
5758
import org.elasticsearch.client.indexlifecycle.RolloverAction;
@@ -645,7 +646,7 @@ public void testDefaultNamedXContents() {
645646

646647
public void testProvidedNamedXContents() {
647648
List<NamedXContentRegistry.Entry> namedXContents = RestHighLevelClient.getProvidedNamedXContents();
648-
assertEquals(17, namedXContents.size());
649+
assertEquals(18, namedXContents.size());
649650
Map<Class<?>, Integer> categories = new HashMap<>();
650651
List<String> names = new ArrayList<>();
651652
for (NamedXContentRegistry.Entry namedXContent : namedXContents) {
@@ -669,13 +670,14 @@ public void testProvidedNamedXContents() {
669670
assertTrue(names.contains(MeanReciprocalRank.NAME));
670671
assertTrue(names.contains(DiscountedCumulativeGain.NAME));
671672
assertTrue(names.contains(ExpectedReciprocalRank.NAME));
672-
assertEquals(Integer.valueOf(6), categories.get(LifecycleAction.class));
673+
assertEquals(Integer.valueOf(7), categories.get(LifecycleAction.class));
673674
assertTrue(names.contains(AllocateAction.NAME));
674675
assertTrue(names.contains(DeleteAction.NAME));
675676
assertTrue(names.contains(ForceMergeAction.NAME));
676677
assertTrue(names.contains(ReadOnlyAction.NAME));
677678
assertTrue(names.contains(RolloverAction.NAME));
678679
assertTrue(names.contains(ShrinkAction.NAME));
680+
assertTrue(names.contains(FreezeAction.NAME));
679681
}
680682

681683
public void testMethodWithHeadersArgumentAreDeprecated() {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client.indexlifecycle;
20+
21+
import org.elasticsearch.common.xcontent.XContentParser;
22+
import org.elasticsearch.test.AbstractXContentTestCase;
23+
24+
public class FreezeActionTests extends AbstractXContentTestCase<FreezeAction> {
25+
26+
@Override
27+
protected FreezeAction createTestInstance() {
28+
return new FreezeAction();
29+
}
30+
31+
@Override
32+
protected FreezeAction doParseInstance(XContentParser parser) {
33+
return FreezeAction.parse(parser);
34+
}
35+
36+
@Override
37+
protected boolean supportsUnknownFields() {
38+
return false;
39+
}
40+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/indexlifecycle/GetLifecyclePolicyResponseTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ protected NamedXContentRegistry xContentRegistry() {
6666
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse),
6767
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
6868
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
69-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse)
69+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
70+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
7071
));
7172
return new NamedXContentRegistry(entries);
7273
}

client/rest-high-level/src/test/java/org/elasticsearch/client/indexlifecycle/LifecyclePolicyMetadataTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ protected NamedXContentRegistry xContentRegistry() {
6262
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse),
6363
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
6464
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
65-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse)
65+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
66+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
6667
));
6768
return new NamedXContentRegistry(entries);
6869
}

client/rest-high-level/src/test/java/org/elasticsearch/client/indexlifecycle/LifecyclePolicyTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class LifecyclePolicyTests extends AbstractXContentTestCase<LifecyclePoli
4242
private static final Set<String> VALID_HOT_ACTIONS = Sets.newHashSet(RolloverAction.NAME);
4343
private static final Set<String> VALID_WARM_ACTIONS = Sets.newHashSet(AllocateAction.NAME, ForceMergeAction.NAME,
4444
ReadOnlyAction.NAME, ShrinkAction.NAME);
45-
private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(AllocateAction.NAME);
45+
private static final Set<String> VALID_COLD_ACTIONS = Sets.newHashSet(AllocateAction.NAME, FreezeAction.NAME);
4646
private static final Set<String> VALID_DELETE_ACTIONS = Sets.newHashSet(DeleteAction.NAME);
4747

4848
private String lifecycleName;
@@ -66,7 +66,8 @@ protected NamedXContentRegistry xContentRegistry() {
6666
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ForceMergeAction.NAME), ForceMergeAction::parse),
6767
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ReadOnlyAction.NAME), ReadOnlyAction::parse),
6868
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(RolloverAction.NAME), RolloverAction::parse),
69-
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse)
69+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(ShrinkAction.NAME), ShrinkAction::parse),
70+
new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(FreezeAction.NAME), FreezeAction::parse)
7071
));
7172
return new NamedXContentRegistry(entries);
7273
}
@@ -207,6 +208,8 @@ public static LifecyclePolicy createRandomPolicy(String lifecycleName) {
207208
return RolloverActionTests.randomInstance();
208209
case ShrinkAction.NAME:
209210
return ShrinkActionTests.randomInstance();
211+
case FreezeAction.NAME:
212+
return new FreezeAction();
210213
default:
211214
throw new IllegalArgumentException("invalid action [" + action + "]");
212215
}};
@@ -236,6 +239,8 @@ private LifecycleAction getTestAction(String actionName) {
236239
return RolloverActionTests.randomInstance();
237240
case ShrinkAction.NAME:
238241
return ShrinkActionTests.randomInstance();
242+
case FreezeAction.NAME:
243+
return new FreezeAction();
239244
default:
240245
throw new IllegalArgumentException("unsupported phase action [" + actionName + "]");
241246
}

docs/reference/ilm/policy-definitions.asciidoc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,39 @@ PUT _ilm/policy/my_policy
284284
--------------------------------------------------
285285
// CONSOLE
286286

287+
[[ilm-freeze-action]]
288+
==== Freeze
289+
290+
Phases allowed: cold.
291+
292+
This action will <<frozen-indices, freeze>> the index
293+
by calling the <<freeze-index-api, Freeze Index API>>.
294+
295+
[source,js]
296+
--------------------------------------------------
297+
PUT _ilm/policy/my_policy
298+
{
299+
"policy": {
300+
"phases": {
301+
"cold": {
302+
"actions": {
303+
"freeze" : { }
304+
}
305+
}
306+
}
307+
}
308+
}
309+
--------------------------------------------------
310+
// CONSOLE
311+
312+
[IMPORTANT]
313+
================================
314+
Freezing an index will close the index and reopen it within the same API call.
315+
This causes primaries to not be allocated for a short amount of time and
316+
causes the cluster to go red until the primaries are allocated again.
317+
This limitation might be removed in the future.
318+
================================
319+
287320
[[ilm-readonly-action]]
288321
==== Read-Only
289322

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.elasticsearch.xpack.core.indexlifecycle.AllocateAction;
4747
import org.elasticsearch.xpack.core.indexlifecycle.DeleteAction;
4848
import org.elasticsearch.xpack.core.indexlifecycle.ForceMergeAction;
49+
import org.elasticsearch.xpack.core.indexlifecycle.FreezeAction;
4950
import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage;
5051
import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata;
5152
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
@@ -423,7 +424,8 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
423424
new NamedWriteableRegistry.Entry(LifecycleAction.class, ReadOnlyAction.NAME, ReadOnlyAction::new),
424425
new NamedWriteableRegistry.Entry(LifecycleAction.class, RolloverAction.NAME, RolloverAction::new),
425426
new NamedWriteableRegistry.Entry(LifecycleAction.class, ShrinkAction.NAME, ShrinkAction::new),
426-
new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new)
427+
new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new),
428+
new NamedWriteableRegistry.Entry(LifecycleAction.class, FreezeAction.NAME, FreezeAction::new)
427429
);
428430
}
429431

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.xpack.core.indexlifecycle;
7+
8+
import org.elasticsearch.client.Client;
9+
import org.elasticsearch.common.Strings;
10+
import org.elasticsearch.common.io.stream.StreamInput;
11+
import org.elasticsearch.common.io.stream.StreamOutput;
12+
import org.elasticsearch.common.xcontent.ObjectParser;
13+
import org.elasticsearch.common.xcontent.XContentBuilder;
14+
import org.elasticsearch.common.xcontent.XContentParser;
15+
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
16+
17+
import java.io.IOException;
18+
import java.util.Arrays;
19+
import java.util.List;
20+
21+
/**
22+
* A {@link LifecycleAction} which freezes the index.
23+
*/
24+
public class FreezeAction implements LifecycleAction {
25+
public static final String NAME = "freeze";
26+
27+
private static final ObjectParser<FreezeAction, Void> PARSER = new ObjectParser<>(NAME, FreezeAction::new);
28+
29+
public static FreezeAction parse(XContentParser parser) {
30+
return PARSER.apply(parser, null);
31+
}
32+
33+
public FreezeAction() {
34+
}
35+
36+
public FreezeAction(StreamInput in) {
37+
}
38+
39+
@Override
40+
public void writeTo(StreamOutput out) throws IOException {
41+
}
42+
43+
@Override
44+
public String getWriteableName() {
45+
return NAME;
46+
}
47+
48+
@Override
49+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
50+
builder.startObject();
51+
builder.endObject();
52+
return builder;
53+
}
54+
55+
@Override
56+
public boolean isSafeAction() {
57+
return true;
58+
}
59+
60+
@Override
61+
public List<Step> toSteps(Client client, String phase, StepKey nextStepKey) {
62+
StepKey freezeStepKey = new StepKey(phase, NAME, FreezeStep.NAME);
63+
FreezeStep freezeStep = new FreezeStep(freezeStepKey, nextStepKey, client);
64+
return Arrays.asList(freezeStep);
65+
}
66+
67+
@Override
68+
public List<StepKey> toStepKeys(String phase) {
69+
StepKey freezeStepKey = new StepKey(phase, NAME, FreezeStep.NAME);
70+
return Arrays.asList(freezeStepKey);
71+
}
72+
73+
@Override
74+
public int hashCode() {
75+
return 1;
76+
}
77+
78+
@Override
79+
public boolean equals(Object obj) {
80+
if (obj == null) {
81+
return false;
82+
}
83+
if (obj.getClass() != getClass()) {
84+
return false;
85+
}
86+
return true;
87+
}
88+
89+
@Override
90+
public String toString() {
91+
return Strings.toString(this);
92+
}
93+
94+
}

0 commit comments

Comments
 (0)