Skip to content

Commit 901aafb

Browse files
authored
add APIs to Maintenance Mode in ILM (#31410)
- POST _xpack/index_lifecycle/_stop - issues a request to be placed into STOPPED mode (maintenance mode). This is not immediate, since we must first verify that it is safe to go from STOPPING -> STOPPED. - POST _xpack/index_lifecycle/_start - issues a request to be placed back into RUNNING mode (immediately) - GET _xpack/index_lifecycle/_status - get back the current mode our lifecycle management is in - update task was hardened to support uninstalled metadata - if no metadata is installed, the start/stop actions will install metadata and proceed to try and change it (default start mode is RUNNING) - rename MAINTENANCE -> STOPPED, MAINTENANCE_REQUESTED -> STOPPING, NORMAL -> RUNNING follow-up to #31164.
1 parent fc2f982 commit 901aafb

23 files changed

+677
-80
lines changed

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

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333

3434
public class IndexLifecycleMetadata implements XPackMetaDataCustom {
3535
public static final String TYPE = "index_lifecycle";
36-
public static final ParseField MAINTENANCE_MODE_FIELD = new ParseField("maintenance_mode");
36+
public static final ParseField OPERATION_MODE_FIELD = new ParseField("operation_mode");
3737
public static final ParseField POLICIES_FIELD = new ParseField("policies");
38-
public static final IndexLifecycleMetadata EMPTY = new IndexLifecycleMetadata(Collections.emptySortedMap(), OperationMode.NORMAL);
38+
public static final IndexLifecycleMetadata EMPTY = new IndexLifecycleMetadata(Collections.emptySortedMap(), OperationMode.RUNNING);
3939

4040
@SuppressWarnings("unchecked")
4141
public static final ConstructingObjectParser<IndexLifecycleMetadata, Void> PARSER = new ConstructingObjectParser<>(
@@ -47,15 +47,15 @@ public class IndexLifecycleMetadata implements XPackMetaDataCustom {
4747
v -> {
4848
throw new IllegalArgumentException("ordered " + POLICIES_FIELD.getPreferredName() + " are not supported");
4949
}, POLICIES_FIELD);
50-
PARSER.declareString(ConstructingObjectParser.constructorArg(), MAINTENANCE_MODE_FIELD);
50+
PARSER.declareString(ConstructingObjectParser.constructorArg(), OPERATION_MODE_FIELD);
5151
}
5252

5353
private final Map<String, LifecyclePolicyMetadata> policyMetadatas;
54-
private final OperationMode maintenanceMode;
54+
private final OperationMode operationMode;
5555

56-
public IndexLifecycleMetadata(Map<String, LifecyclePolicyMetadata> policies, OperationMode maintenanceMode) {
56+
public IndexLifecycleMetadata(Map<String, LifecyclePolicyMetadata> policies, OperationMode operationMode) {
5757
this.policyMetadatas = Collections.unmodifiableMap(policies);
58-
this.maintenanceMode = maintenanceMode;
58+
this.operationMode = operationMode;
5959
}
6060

6161
public IndexLifecycleMetadata(StreamInput in) throws IOException {
@@ -65,7 +65,7 @@ public IndexLifecycleMetadata(StreamInput in) throws IOException {
6565
policies.put(in.readString(), new LifecyclePolicyMetadata(in));
6666
}
6767
this.policyMetadatas = policies;
68-
this.maintenanceMode = in.readEnum(OperationMode.class);
68+
this.operationMode = in.readEnum(OperationMode.class);
6969
}
7070

7171
@Override
@@ -75,15 +75,15 @@ public void writeTo(StreamOutput out) throws IOException {
7575
out.writeString(entry.getKey());
7676
entry.getValue().writeTo(out);
7777
}
78-
out.writeEnum(maintenanceMode);
78+
out.writeEnum(operationMode);
7979
}
8080

8181
public Map<String, LifecyclePolicyMetadata> getPolicyMetadatas() {
8282
return policyMetadatas;
8383
}
8484

85-
public OperationMode getMaintenanceMode() {
86-
return maintenanceMode;
85+
public OperationMode getOperationMode() {
86+
return operationMode;
8787
}
8888

8989
public Map<String, LifecyclePolicy> getPolicies() {
@@ -99,7 +99,7 @@ public Diff<Custom> diff(Custom previousState) {
9999
@Override
100100
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
101101
builder.field(POLICIES_FIELD.getPreferredName(), policyMetadatas);
102-
builder.field(MAINTENANCE_MODE_FIELD.getPreferredName(), maintenanceMode);
102+
builder.field(OPERATION_MODE_FIELD.getPreferredName(), operationMode);
103103
return builder;
104104
}
105105

@@ -120,7 +120,7 @@ public EnumSet<MetaData.XContentContext> context() {
120120

121121
@Override
122122
public int hashCode() {
123-
return Objects.hash(policyMetadatas, maintenanceMode);
123+
return Objects.hash(policyMetadatas, operationMode);
124124
}
125125

126126
@Override
@@ -133,7 +133,7 @@ public boolean equals(Object obj) {
133133
}
134134
IndexLifecycleMetadata other = (IndexLifecycleMetadata) obj;
135135
return Objects.equals(policyMetadatas, other.policyMetadatas)
136-
&& Objects.equals(maintenanceMode, other.maintenanceMode);
136+
&& Objects.equals(operationMode, other.operationMode);
137137
}
138138

139139
@Override
@@ -144,30 +144,30 @@ public String toString() {
144144
public static class IndexLifecycleMetadataDiff implements NamedDiff<MetaData.Custom> {
145145

146146
final Diff<Map<String, LifecyclePolicyMetadata>> policies;
147-
final OperationMode maintenanceMode;
147+
final OperationMode operationMode;
148148

149149
IndexLifecycleMetadataDiff(IndexLifecycleMetadata before, IndexLifecycleMetadata after) {
150150
this.policies = DiffableUtils.diff(before.policyMetadatas, after.policyMetadatas, DiffableUtils.getStringKeySerializer());
151-
this.maintenanceMode = after.maintenanceMode;
151+
this.operationMode = after.operationMode;
152152
}
153153

154154
public IndexLifecycleMetadataDiff(StreamInput in) throws IOException {
155155
this.policies = DiffableUtils.readJdkMapDiff(in, DiffableUtils.getStringKeySerializer(), LifecyclePolicyMetadata::new,
156156
IndexLifecycleMetadataDiff::readLifecyclePolicyDiffFrom);
157-
this.maintenanceMode = in.readEnum(OperationMode.class);
157+
this.operationMode = in.readEnum(OperationMode.class);
158158
}
159159

160160
@Override
161161
public MetaData.Custom apply(MetaData.Custom part) {
162162
TreeMap<String, LifecyclePolicyMetadata> newPolicies = new TreeMap<>(
163163
policies.apply(((IndexLifecycleMetadata) part).policyMetadatas));
164-
return new IndexLifecycleMetadata(newPolicies, this.maintenanceMode);
164+
return new IndexLifecycleMetadata(newPolicies, this.operationMode);
165165
}
166166

167167
@Override
168168
public void writeTo(StreamOutput out) throws IOException {
169169
policies.writeTo(out);
170-
out.writeEnum(maintenanceMode);
170+
out.writeEnum(operationMode);
171171
}
172172

173173
@Override

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,31 @@ public enum OperationMode {
1212
/**
1313
* This represents a state where no policies are executed
1414
*/
15-
MAINTENANCE {
15+
STOPPED {
1616
@Override
1717
public boolean isValidChange(OperationMode nextMode) {
18-
return nextMode == NORMAL;
18+
return nextMode == RUNNING;
1919
}
2020
},
2121

2222
/**
23-
* this representes a state where only sensitive actions (like {@link ShrinkAction}) will be executed
24-
* until they finish, at which point the operation mode will move to maintenance mode.
23+
* this represents a state where only sensitive actions (like {@link ShrinkAction}) will be executed
24+
* until they finish, at which point the operation mode will move to <code>STOPPED</code>.
2525
*/
26-
MAINTENANCE_REQUESTED {
26+
STOPPING {
2727
@Override
2828
public boolean isValidChange(OperationMode nextMode) {
29-
return nextMode == NORMAL || nextMode == MAINTENANCE;
29+
return nextMode == RUNNING || nextMode == STOPPED;
3030
}
3131
},
3232

3333
/**
3434
* Normal operation where all policies are executed as normal.
3535
*/
36-
NORMAL {
36+
RUNNING {
3737
@Override
3838
public boolean isValidChange(OperationMode nextMode) {
39-
return nextMode == MAINTENANCE_REQUESTED;
39+
return nextMode == STOPPING;
4040
}
4141
};
4242

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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.action;
7+
8+
import org.elasticsearch.action.Action;
9+
import org.elasticsearch.action.ActionRequestValidationException;
10+
import org.elasticsearch.action.ActionResponse;
11+
import org.elasticsearch.action.support.master.AcknowledgedRequest;
12+
import org.elasticsearch.common.Strings;
13+
import org.elasticsearch.common.io.stream.StreamInput;
14+
import org.elasticsearch.common.io.stream.StreamOutput;
15+
import org.elasticsearch.common.xcontent.ToXContentObject;
16+
import org.elasticsearch.common.xcontent.XContentBuilder;
17+
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
18+
19+
import java.io.IOException;
20+
import java.util.Objects;
21+
22+
public class GetStatusAction extends Action<GetStatusAction.Response> {
23+
public static final GetStatusAction INSTANCE = new GetStatusAction();
24+
public static final String NAME = "cluster:admin/xpack/index_lifecycle/operation_mode/get";
25+
26+
protected GetStatusAction() {
27+
super(NAME);
28+
}
29+
30+
@Override
31+
public Response newResponse() {
32+
return new Response();
33+
}
34+
35+
public static class Response extends ActionResponse implements ToXContentObject {
36+
37+
private OperationMode mode;
38+
39+
public Response() {
40+
}
41+
42+
public Response(OperationMode mode) {
43+
this.mode = mode;
44+
}
45+
46+
public OperationMode getMode() {
47+
return mode;
48+
}
49+
50+
@Override
51+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
52+
builder.startObject();
53+
builder.field("operation_mode", mode);
54+
builder.endObject();
55+
return builder;
56+
}
57+
58+
@Override
59+
public void readFrom(StreamInput in) throws IOException {
60+
mode = in.readEnum(OperationMode.class);
61+
}
62+
63+
@Override
64+
public void writeTo(StreamOutput out) throws IOException {
65+
out.writeEnum(mode);
66+
}
67+
68+
@Override
69+
public int hashCode() {
70+
return Objects.hash(mode);
71+
}
72+
73+
@Override
74+
public boolean equals(Object obj) {
75+
if (obj == null) {
76+
return false;
77+
}
78+
if (obj.getClass() != getClass()) {
79+
return false;
80+
}
81+
Response other = (Response) obj;
82+
return Objects.equals(mode, other.mode);
83+
}
84+
85+
@Override
86+
public String toString() {
87+
return Strings.toString(this, true, true);
88+
}
89+
90+
}
91+
92+
public static class Request extends AcknowledgedRequest<Request> {
93+
94+
public Request() {
95+
}
96+
97+
@Override
98+
public ActionRequestValidationException validate() {
99+
return null;
100+
}
101+
102+
@Override
103+
public void readFrom(StreamInput in) throws IOException {
104+
super.readFrom(in);
105+
}
106+
107+
@Override
108+
public void writeTo(StreamOutput out) throws IOException {
109+
super.writeTo(out);
110+
}
111+
}
112+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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.action;
7+
8+
import org.elasticsearch.action.Action;
9+
import org.elasticsearch.action.ActionRequestValidationException;
10+
import org.elasticsearch.action.support.master.AcknowledgedRequest;
11+
import org.elasticsearch.action.support.master.AcknowledgedResponse;
12+
import org.elasticsearch.common.io.stream.StreamInput;
13+
import org.elasticsearch.common.io.stream.StreamOutput;
14+
import org.elasticsearch.common.xcontent.ToXContentObject;
15+
import org.elasticsearch.xpack.core.indexlifecycle.OperationMode;
16+
17+
import java.io.IOException;
18+
import java.util.Objects;
19+
20+
public class PutOperationModeAction extends Action<PutOperationModeAction.Response> {
21+
public static final PutOperationModeAction INSTANCE = new PutOperationModeAction();
22+
public static final String NAME = "cluster:admin/xpack/index_lifecycle/operation_mode/set";
23+
24+
protected PutOperationModeAction() {
25+
super(NAME);
26+
}
27+
28+
@Override
29+
public Response newResponse() {
30+
return new Response();
31+
}
32+
33+
public static class Response extends AcknowledgedResponse implements ToXContentObject {
34+
35+
public Response() {
36+
}
37+
38+
public Response(boolean acknowledged) {
39+
super(acknowledged);
40+
}
41+
}
42+
43+
public static class Request extends AcknowledgedRequest<Request> {
44+
45+
private OperationMode mode;
46+
47+
public Request(OperationMode mode) {
48+
this.mode = mode;
49+
}
50+
51+
public Request() {
52+
}
53+
54+
public OperationMode getMode() {
55+
return mode;
56+
}
57+
58+
@Override
59+
public ActionRequestValidationException validate() {
60+
if (mode == OperationMode.STOPPED) {
61+
ActionRequestValidationException exception = new ActionRequestValidationException();
62+
exception.addValidationError("cannot directly stop index-lifecycle");
63+
return exception;
64+
}
65+
return null;
66+
}
67+
68+
@Override
69+
public void readFrom(StreamInput in) throws IOException {
70+
super.readFrom(in);
71+
mode = in.readEnum(OperationMode.class);
72+
}
73+
74+
@Override
75+
public void writeTo(StreamOutput out) throws IOException {
76+
super.writeTo(out);
77+
out.writeEnum(mode);
78+
}
79+
80+
@Override
81+
public int hashCode() {
82+
return Objects.hash(mode);
83+
}
84+
85+
@Override
86+
public boolean equals(Object obj) {
87+
if (obj == null) {
88+
return false;
89+
}
90+
if (obj.getClass() != getClass()) {
91+
return false;
92+
}
93+
Request other = (Request) obj;
94+
return Objects.equals(mode, other.mode);
95+
}
96+
}
97+
98+
}

0 commit comments

Comments
 (0)