Skip to content

Commit 43a1208

Browse files
nielsbaumanmridula-s109
authored andcommitted
Make ILM operation mode APIs project-aware (elastic#129678)
Also updates the lifecycle service.
1 parent 045e06e commit 43a1208

File tree

8 files changed

+73
-44
lines changed

8 files changed

+73
-44
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,21 @@ public static OperationMode currentILMMode(final ProjectMetadata projectMetadata
8080
);
8181
}
8282

83+
@Deprecated(forRemoval = true)
84+
public static OperationMode currentSLMMode(final ClusterState state) {
85+
return currentSLMMode(state.metadata().getProject());
86+
}
87+
8388
/**
8489
* Returns the current ILM mode based on the given cluster state. It first checks the newer
8590
* storage mechanism ({@link LifecycleOperationMetadata#getSLMOperationMode()}) before falling
8691
* back to {@link SnapshotLifecycleMetadata#getOperationMode()}. If neither exist, the default
8792
* value for an empty state is used.
8893
*/
8994
@SuppressWarnings("deprecated")
90-
public static OperationMode currentSLMMode(final ClusterState state) {
91-
SnapshotLifecycleMetadata oldMetadata = state.metadata().getProject().custom(SnapshotLifecycleMetadata.TYPE);
92-
LifecycleOperationMetadata currentMetadata = state.metadata().getProject().custom(LifecycleOperationMetadata.TYPE);
95+
public static OperationMode currentSLMMode(ProjectMetadata project) {
96+
SnapshotLifecycleMetadata oldMetadata = project.custom(SnapshotLifecycleMetadata.TYPE);
97+
LifecycleOperationMetadata currentMetadata = project.custom(LifecycleOperationMetadata.TYPE);
9398
return Optional.ofNullable(currentMetadata)
9499
.map(LifecycleOperationMetadata::getSLMOperationMode)
95100
.orElse(

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

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
import org.elasticsearch.cluster.AckedClusterStateUpdateTask;
1515
import org.elasticsearch.cluster.ClusterState;
1616
import org.elasticsearch.cluster.ClusterStateUpdateTask;
17+
import org.elasticsearch.cluster.metadata.ProjectId;
18+
import org.elasticsearch.cluster.metadata.ProjectMetadata;
1719
import org.elasticsearch.common.Priority;
20+
import org.elasticsearch.core.FixForMultiProject;
1821
import org.elasticsearch.core.Nullable;
1922
import org.elasticsearch.core.Strings;
2023

@@ -29,6 +32,8 @@
2932
*/
3033
public class OperationModeUpdateTask extends ClusterStateUpdateTask {
3134
private static final Logger logger = LogManager.getLogger(OperationModeUpdateTask.class);
35+
36+
private final ProjectId projectId;
3237
@Nullable
3338
private final OperationMode ilmMode;
3439
@Nullable
@@ -47,18 +52,21 @@ public ClusterState execute(ClusterState currentState) {
4752
};
4853
}
4954

50-
private OperationModeUpdateTask(Priority priority, OperationMode ilmMode, OperationMode slmMode) {
55+
private OperationModeUpdateTask(Priority priority, ProjectId projectId, OperationMode ilmMode, OperationMode slmMode) {
5156
super(priority);
57+
this.projectId = projectId;
5258
this.ilmMode = ilmMode;
5359
this.slmMode = slmMode;
5460
}
5561

56-
public static OperationModeUpdateTask ilmMode(OperationMode mode) {
57-
return new OperationModeUpdateTask(getPriority(mode), mode, null);
62+
public static OperationModeUpdateTask ilmMode(ProjectId projectId, OperationMode mode) {
63+
return new OperationModeUpdateTask(getPriority(mode), projectId, mode, null);
5864
}
5965

6066
public static OperationModeUpdateTask slmMode(OperationMode mode) {
61-
return new OperationModeUpdateTask(getPriority(mode), null, mode);
67+
@FixForMultiProject // Use non-default ID when SLM has been made project-aware
68+
final var projectId = ProjectId.DEFAULT;
69+
return new OperationModeUpdateTask(getPriority(mode), projectId, null, mode);
6270
}
6371

6472
private static Priority getPriority(OperationMode mode) {
@@ -79,60 +87,61 @@ public OperationMode getSLMOperationMode() {
7987

8088
@Override
8189
public ClusterState execute(ClusterState currentState) {
82-
ClusterState newState = currentState;
83-
newState = updateILMState(newState);
84-
newState = updateSLMState(newState);
85-
return newState;
90+
ProjectMetadata oldProject = currentState.metadata().getProject(projectId);
91+
ProjectMetadata newProject = updateILMState(oldProject);
92+
newProject = updateSLMState(newProject);
93+
if (newProject == oldProject) {
94+
return currentState;
95+
}
96+
return ClusterState.builder(currentState).putProjectMetadata(newProject).build();
8697
}
8798

88-
private ClusterState updateILMState(final ClusterState currentState) {
99+
private ProjectMetadata updateILMState(final ProjectMetadata currentProject) {
89100
if (ilmMode == null) {
90-
return currentState;
101+
return currentProject;
91102
}
92103

93-
final var project = currentState.metadata().getProject();
94-
final OperationMode currentMode = currentILMMode(project);
104+
final OperationMode currentMode = currentILMMode(currentProject);
95105
if (currentMode.equals(ilmMode)) {
96106
// No need for a new state
97-
return currentState;
107+
return currentProject;
98108
}
99109

100110
final OperationMode newMode;
101111
if (currentMode.isValidChange(ilmMode)) {
102112
newMode = ilmMode;
103113
} else {
104114
// The transition is invalid, return the current state
105-
return currentState;
115+
return currentProject;
106116
}
107117

108118
logger.info("updating ILM operation mode to {}", newMode);
109-
final var updatedMetadata = new LifecycleOperationMetadata(newMode, currentSLMMode(currentState));
110-
return currentState.copyAndUpdateProject(project.id(), b -> b.putCustom(LifecycleOperationMetadata.TYPE, updatedMetadata));
119+
final var updatedMetadata = new LifecycleOperationMetadata(newMode, currentSLMMode(currentProject));
120+
return currentProject.copyAndUpdate(b -> b.putCustom(LifecycleOperationMetadata.TYPE, updatedMetadata));
111121
}
112122

113-
private ClusterState updateSLMState(final ClusterState currentState) {
123+
private ProjectMetadata updateSLMState(final ProjectMetadata currentProject) {
114124
if (slmMode == null) {
115-
return currentState;
125+
return currentProject;
116126
}
117127

118-
final var project = currentState.metadata().getProject();
119-
final OperationMode currentMode = currentSLMMode(currentState);
128+
final OperationMode currentMode = currentSLMMode(currentProject);
120129
if (currentMode.equals(slmMode)) {
121130
// No need for a new state
122-
return currentState;
131+
return currentProject;
123132
}
124133

125134
final OperationMode newMode;
126135
if (currentMode.isValidChange(slmMode)) {
127136
newMode = slmMode;
128137
} else {
129138
// The transition is invalid, return the current state
130-
return currentState;
139+
return currentProject;
131140
}
132141

133142
logger.info("updating SLM operation mode to {}", newMode);
134-
final var updatedMetadata = new LifecycleOperationMetadata(currentILMMode(project), newMode);
135-
return currentState.copyAndUpdateProject(project.id(), b -> b.putCustom(LifecycleOperationMetadata.TYPE, updatedMetadata));
143+
final var updatedMetadata = new LifecycleOperationMetadata(currentILMMode(currentProject), newMode);
144+
return currentProject.copyAndUpdate(b -> b.putCustom(LifecycleOperationMetadata.TYPE, updatedMetadata));
136145
}
137146

138147
@Override

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/OperationModeUpdateTaskTests.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.elasticsearch.cluster.ClusterName;
1010
import org.elasticsearch.cluster.ClusterState;
1111
import org.elasticsearch.cluster.metadata.Metadata;
12+
import org.elasticsearch.cluster.metadata.ProjectMetadata;
1213
import org.elasticsearch.index.IndexVersion;
1314
import org.elasticsearch.test.ESTestCase;
1415
import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata;
@@ -102,23 +103,23 @@ private OperationMode executeILMUpdate(
102103
currentMode,
103104
new SnapshotLifecycleStats()
104105
);
105-
Metadata.Builder metadata = Metadata.builder().persistentSettings(settings(IndexVersion.current()).build());
106+
ProjectMetadata.Builder project = ProjectMetadata.builder(randomProjectIdOrDefault());
106107
if (metadataInstalled) {
107-
metadata.projectCustoms(
108+
project.customs(
108109
Map.of(IndexLifecycleMetadata.TYPE, indexLifecycleMetadata, SnapshotLifecycleMetadata.TYPE, snapshotLifecycleMetadata)
109110
);
110111
}
111-
ClusterState state = ClusterState.builder(ClusterName.DEFAULT).metadata(metadata).build();
112-
OperationModeUpdateTask task = OperationModeUpdateTask.ilmMode(requestMode);
112+
ClusterState state = ClusterState.builder(ClusterName.DEFAULT).putProjectMetadata(project).build();
113+
OperationModeUpdateTask task = OperationModeUpdateTask.ilmMode(project.getId(), requestMode);
113114
ClusterState newState = task.execute(state);
114115
if (assertSameClusterState) {
115116
assertSame("expected the same state instance but they were different", state, newState);
116117
} else {
117118
assertThat("expected a different state instance but they were the same", state, not(equalTo(newState)));
118119
}
119-
LifecycleOperationMetadata newMetadata = newState.metadata().getProject().custom(LifecycleOperationMetadata.TYPE);
120+
LifecycleOperationMetadata newMetadata = newState.metadata().getProject(project.getId()).custom(LifecycleOperationMetadata.TYPE);
120121
IndexLifecycleMetadata oldMetadata = newState.metadata()
121-
.getProject()
122+
.getProject(project.getId())
122123
.custom(IndexLifecycleMetadata.TYPE, IndexLifecycleMetadata.EMPTY);
123124
return Optional.ofNullable(newMetadata)
124125
.map(LifecycleOperationMetadata::getILMOperationMode)

x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleService.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.elasticsearch.cluster.ProjectState;
1919
import org.elasticsearch.cluster.metadata.IndexMetadata;
2020
import org.elasticsearch.cluster.metadata.LifecycleExecutionState;
21+
import org.elasticsearch.cluster.metadata.ProjectId;
2122
import org.elasticsearch.cluster.metadata.ProjectMetadata;
2223
import org.elasticsearch.cluster.metadata.SingleNodeShutdownMetadata;
2324
import org.elasticsearch.cluster.service.ClusterService;
@@ -262,13 +263,13 @@ void onMaster(ProjectState state) {
262263
}
263264

264265
if (safeToStop && OperationMode.STOPPING == currentMode) {
265-
stopILM();
266+
stopILM(state.projectId());
266267
}
267268
}
268269
}
269270

270-
private void stopILM() {
271-
submitUnbatchedTask("ilm_operation_mode_update[stopped]", OperationModeUpdateTask.ilmMode(OperationMode.STOPPED));
271+
private void stopILM(ProjectId projectId) {
272+
submitUnbatchedTask("ilm_operation_mode_update[stopped]", OperationModeUpdateTask.ilmMode(projectId, OperationMode.STOPPED));
272273
}
273274

274275
@Override
@@ -479,7 +480,7 @@ void triggerPolicies(ProjectState state, boolean fromClusterStateChange) {
479480
if (currentMetadata == null) {
480481
if (currentMode == OperationMode.STOPPING) {
481482
// There are no policies and ILM is in stopping mode, so stop ILM and get out of here
482-
stopILM();
483+
stopILM(state.projectId());
483484
}
484485
return;
485486
}
@@ -562,7 +563,7 @@ void triggerPolicies(ProjectState state, boolean fromClusterStateChange) {
562563
}
563564

564565
if (safeToStop && OperationMode.STOPPING == currentMode) {
565-
stopILM();
566+
stopILM(state.projectId());
566567
}
567568
}
568569

x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/action/TransportStartILMAction.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.elasticsearch.cluster.ClusterStateUpdateTask;
1616
import org.elasticsearch.cluster.block.ClusterBlockException;
1717
import org.elasticsearch.cluster.block.ClusterBlockLevel;
18+
import org.elasticsearch.cluster.project.ProjectResolver;
1819
import org.elasticsearch.cluster.service.ClusterService;
1920
import org.elasticsearch.common.util.concurrent.EsExecutors;
2021
import org.elasticsearch.core.SuppressForbidden;
@@ -29,12 +30,15 @@
2930

3031
public class TransportStartILMAction extends AcknowledgedTransportMasterNodeAction<StartILMRequest> {
3132

33+
private final ProjectResolver projectResolver;
34+
3235
@Inject
3336
public TransportStartILMAction(
3437
TransportService transportService,
3538
ClusterService clusterService,
3639
ThreadPool threadPool,
37-
ActionFilters actionFilters
40+
ActionFilters actionFilters,
41+
ProjectResolver projectResolver
3842
) {
3943
super(
4044
ILMActions.START.name(),
@@ -45,13 +49,15 @@ public TransportStartILMAction(
4549
StartILMRequest::new,
4650
EsExecutors.DIRECT_EXECUTOR_SERVICE
4751
);
52+
this.projectResolver = projectResolver;
4853
}
4954

5055
@Override
5156
protected void masterOperation(Task task, StartILMRequest request, ClusterState state, ActionListener<AcknowledgedResponse> listener) {
57+
final var projectId = projectResolver.getProjectId();
5258
submitUnbatchedTask(
5359
"ilm_operation_mode_update[running]",
54-
OperationModeUpdateTask.wrap(OperationModeUpdateTask.ilmMode(OperationMode.RUNNING), request, listener)
60+
OperationModeUpdateTask.wrap(OperationModeUpdateTask.ilmMode(projectId, OperationMode.RUNNING), request, listener)
5561
);
5662
}
5763

x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/action/TransportStopILMAction.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.elasticsearch.cluster.ClusterStateUpdateTask;
1616
import org.elasticsearch.cluster.block.ClusterBlockException;
1717
import org.elasticsearch.cluster.block.ClusterBlockLevel;
18+
import org.elasticsearch.cluster.project.ProjectResolver;
1819
import org.elasticsearch.cluster.service.ClusterService;
1920
import org.elasticsearch.common.util.concurrent.EsExecutors;
2021
import org.elasticsearch.core.SuppressForbidden;
@@ -29,12 +30,15 @@
2930

3031
public class TransportStopILMAction extends AcknowledgedTransportMasterNodeAction<StopILMRequest> {
3132

33+
private final ProjectResolver projectResolver;
34+
3235
@Inject
3336
public TransportStopILMAction(
3437
TransportService transportService,
3538
ClusterService clusterService,
3639
ThreadPool threadPool,
37-
ActionFilters actionFilters
40+
ActionFilters actionFilters,
41+
ProjectResolver projectResolver
3842
) {
3943
super(
4044
ILMActions.STOP.name(),
@@ -45,13 +49,15 @@ public TransportStopILMAction(
4549
StopILMRequest::new,
4650
EsExecutors.DIRECT_EXECUTOR_SERVICE
4751
);
52+
this.projectResolver = projectResolver;
4853
}
4954

5055
@Override
5156
protected void masterOperation(Task task, StopILMRequest request, ClusterState state, ActionListener<AcknowledgedResponse> listener) {
57+
final var projectId = projectResolver.getProjectId();
5258
submitUnbatchedTask(
5359
"ilm_operation_mode_update[stopping]",
54-
OperationModeUpdateTask.wrap(OperationModeUpdateTask.ilmMode(OperationMode.STOPPING), request, listener)
60+
OperationModeUpdateTask.wrap(OperationModeUpdateTask.ilmMode(projectId, OperationMode.STOPPING), request, listener)
5561
);
5662
}
5763

x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/action/TransportStopILMActionTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.elasticsearch.action.support.ActionFilters;
1212
import org.elasticsearch.cluster.AckedClusterStateUpdateTask;
1313
import org.elasticsearch.cluster.ClusterState;
14+
import org.elasticsearch.cluster.project.TestProjectResolvers;
1415
import org.elasticsearch.cluster.service.ClusterService;
1516
import org.elasticsearch.common.Priority;
1617
import org.elasticsearch.tasks.Task;
@@ -41,7 +42,8 @@ public void testStopILMClusterStatePriorityIsImmediate() {
4142
transportService,
4243
clusterService,
4344
threadPool,
44-
mock(ActionFilters.class)
45+
mock(ActionFilters.class),
46+
TestProjectResolvers.singleProject(randomProjectIdOrDefault())
4547
);
4648
Task task = new Task(
4749
randomLong(),

x-pack/qa/multi-project/xpack-rest-tests-with-multiple-projects/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ tasks.named("yamlRestTest").configure {
4646
'^esql/191_lookup_join_text/*',
4747
'^esql/192_lookup_join_on_aliases/*',
4848
'^health/10_usage/*',
49-
'^ilm/60_operation_mode/*',
5049
'^ilm/80_health/*',
5150
'^logsdb/10_usage/*',
5251
'^migrate/10_reindex/*',

0 commit comments

Comments
 (0)