Skip to content

Commit 3ce4ded

Browse files
committed
Migrate lifecycle deletion logic to metadata service
1 parent a151ac3 commit 3ce4ded

File tree

4 files changed

+73
-75
lines changed

4 files changed

+73
-75
lines changed

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

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import org.apache.logging.log4j.LogManager;
1111
import org.apache.logging.log4j.Logger;
12+
import org.elasticsearch.ResourceNotFoundException;
1213
import org.elasticsearch.action.ActionListener;
1314
import org.elasticsearch.action.support.master.AcknowledgedResponse;
1415
import org.elasticsearch.client.internal.Client;
@@ -25,6 +26,7 @@
2526
import org.elasticsearch.cluster.service.MasterServiceTaskQueue;
2627
import org.elasticsearch.common.Priority;
2728
import org.elasticsearch.core.Nullable;
29+
import org.elasticsearch.core.TimeValue;
2830
import org.elasticsearch.core.Tuple;
2931
import org.elasticsearch.license.XPackLicenseState;
3032
import org.elasticsearch.reservedstate.ReservedClusterStateHandler;
@@ -37,6 +39,7 @@
3739
import org.elasticsearch.xpack.core.ilm.Phase;
3840
import org.elasticsearch.xpack.core.ilm.SearchableSnapshotAction;
3941
import org.elasticsearch.xpack.core.ilm.WaitForSnapshotAction;
42+
import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction;
4043
import org.elasticsearch.xpack.core.ilm.action.PutLifecycleRequest;
4144
import org.elasticsearch.xpack.core.slm.SnapshotLifecycleMetadata;
4245
import org.elasticsearch.xpack.ilm.action.ReservedLifecycleAction;
@@ -61,7 +64,7 @@ public class LifecycleMetadataService {
6164
private final XPackLicenseState licenseState;
6265
private final ThreadPool threadPool;
6366
private final ProjectResolver projectResolver;
64-
private final MasterServiceTaskQueue<UpdateLifecyclePolicyTask> taskQueue;
67+
private final MasterServiceTaskQueue<AckedClusterStateUpdateTask> taskQueue;
6568

6669
public LifecycleMetadataService(
6770
ClusterService clusterService,
@@ -76,7 +79,7 @@ public LifecycleMetadataService(
7679
this.licenseState = licenseState;
7780
this.threadPool = threadPool;
7881
this.projectResolver = projectResolver;
79-
this.taskQueue = clusterService.createTaskQueue("ilm-put-lifecycle-queue", Priority.NORMAL, new IlmLifecycleExecutor());
82+
this.taskQueue = clusterService.createTaskQueue("ilm-lifecycle-queue", Priority.NORMAL, new IlmLifecycleExecutor());
8083
}
8184

8285
public void addLifecycle(PutLifecycleRequest request, ClusterState state, ActionListener<AcknowledgedResponse> listener) {
@@ -305,9 +308,64 @@ public ClusterState execute(ClusterState currentState) throws Exception {
305308
}
306309
}
307310

308-
private static class IlmLifecycleExecutor extends SimpleBatchedAckListenerTaskExecutor<UpdateLifecyclePolicyTask> {
311+
public void deleteLifecycle(DeleteLifecycleAction.Request request, ActionListener<AcknowledgedResponse> listener) {
312+
final var projectId = projectResolver.getProjectId();
313+
DeleteLifecyclePolicyTask deleteTask = new DeleteLifecyclePolicyTask(
314+
projectId,
315+
request.getPolicyName(),
316+
request.masterNodeTimeout(),
317+
request.ackTimeout(),
318+
listener
319+
);
320+
taskQueue.submitTask("delete-lifecycle-" + request.getPolicyName(), deleteTask, deleteTask.timeout());
321+
}
322+
323+
public static class DeleteLifecyclePolicyTask extends AckedClusterStateUpdateTask {
324+
private final ProjectId projectId;
325+
private final String policyName;
326+
327+
public DeleteLifecyclePolicyTask(
328+
ProjectId projectId,
329+
String policyName,
330+
TimeValue masterNodeTimeout,
331+
TimeValue ackTimeout,
332+
ActionListener<AcknowledgedResponse> listener
333+
) {
334+
super(masterNodeTimeout, ackTimeout, listener);
335+
this.projectId = projectId;
336+
this.policyName = policyName;
337+
}
338+
339+
@Override
340+
public ClusterState execute(ClusterState currentState) {
341+
ProjectMetadata projectMetadata = currentState.metadata().getProject(projectId);
342+
List<String> indicesUsingPolicy = projectMetadata.indices()
343+
.values()
344+
.stream()
345+
.filter(idxMeta -> policyName.equals(idxMeta.getLifecyclePolicyName()))
346+
.map(idxMeta -> idxMeta.getIndex().getName())
347+
.toList();
348+
if (indicesUsingPolicy.isEmpty() == false) {
349+
throw new IllegalArgumentException(
350+
"Cannot delete policy [" + policyName + "]. It is in use by one or more indices: " + indicesUsingPolicy
351+
);
352+
}
353+
IndexLifecycleMetadata currentMetadata = projectMetadata.custom(IndexLifecycleMetadata.TYPE);
354+
if (currentMetadata == null || currentMetadata.getPolicyMetadatas().containsKey(policyName) == false) {
355+
throw new ResourceNotFoundException("Lifecycle policy not found: {}", policyName);
356+
}
357+
SortedMap<String, LifecyclePolicyMetadata> newPolicies = new TreeMap<>(currentMetadata.getPolicyMetadatas());
358+
newPolicies.remove(policyName);
359+
IndexLifecycleMetadata newMetadata = new IndexLifecycleMetadata(newPolicies, currentILMMode(projectMetadata));
360+
ProjectMetadata.Builder newProjectMetadata = ProjectMetadata.builder(projectMetadata)
361+
.putCustom(IndexLifecycleMetadata.TYPE, newMetadata);
362+
return ClusterState.builder(currentState).putProjectMetadata(newProjectMetadata).build();
363+
}
364+
}
365+
366+
private static class IlmLifecycleExecutor extends SimpleBatchedAckListenerTaskExecutor<AckedClusterStateUpdateTask> {
309367
@Override
310-
public Tuple<ClusterState, ClusterStateAckListener> executeTask(UpdateLifecyclePolicyTask task, ClusterState clusterState)
368+
public Tuple<ClusterState, ClusterStateAckListener> executeTask(AckedClusterStateUpdateTask task, ClusterState clusterState)
311369
throws Exception {
312370
return Tuple.tuple(task.execute(clusterState), task);
313371
}

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.elasticsearch.xcontent.XContentParser;
2121
import org.elasticsearch.xcontent.XContentParserConfiguration;
2222
import org.elasticsearch.xpack.core.ilm.LifecyclePolicy;
23-
import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction;
2423
import org.elasticsearch.xpack.core.ilm.action.PutLifecycleRequest;
2524
import org.elasticsearch.xpack.ilm.LifecycleMetadataService;
2625

@@ -104,13 +103,11 @@ public TransformState transform(ProjectId projectId, List<LifecyclePolicy> sourc
104103
toDelete.removeAll(entities);
105104

106105
for (var policyToDelete : toDelete) {
107-
TransportDeleteLifecycleAction.DeleteLifecyclePolicyTask task = new TransportDeleteLifecycleAction.DeleteLifecyclePolicyTask(
106+
LifecycleMetadataService.DeleteLifecyclePolicyTask task = new LifecycleMetadataService.DeleteLifecyclePolicyTask(
108107
state.metadata().getProject(projectId).id(),
109-
new DeleteLifecycleAction.Request(
110-
RESERVED_CLUSTER_STATE_HANDLER_IGNORED_TIMEOUT,
111-
RESERVED_CLUSTER_STATE_HANDLER_IGNORED_TIMEOUT,
112-
policyToDelete
113-
),
108+
policyToDelete,
109+
RESERVED_CLUSTER_STATE_HANDLER_IGNORED_TIMEOUT,
110+
RESERVED_CLUSTER_STATE_HANDLER_IGNORED_TIMEOUT,
114111
ActionListener.noop()
115112
);
116113
state = task.execute(state);

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

Lines changed: 5 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,37 @@
77

88
package org.elasticsearch.xpack.ilm.action;
99

10-
import org.elasticsearch.ResourceNotFoundException;
1110
import org.elasticsearch.action.ActionListener;
1211
import org.elasticsearch.action.support.ActionFilters;
1312
import org.elasticsearch.action.support.master.AcknowledgedResponse;
1413
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
15-
import org.elasticsearch.cluster.AckedClusterStateUpdateTask;
1614
import org.elasticsearch.cluster.ClusterState;
17-
import org.elasticsearch.cluster.ClusterStateUpdateTask;
1815
import org.elasticsearch.cluster.block.ClusterBlockException;
1916
import org.elasticsearch.cluster.block.ClusterBlockLevel;
20-
import org.elasticsearch.cluster.metadata.ProjectId;
21-
import org.elasticsearch.cluster.metadata.ProjectMetadata;
22-
import org.elasticsearch.cluster.project.ProjectResolver;
2317
import org.elasticsearch.cluster.service.ClusterService;
2418
import org.elasticsearch.common.util.concurrent.EsExecutors;
25-
import org.elasticsearch.core.SuppressForbidden;
2619
import org.elasticsearch.injection.guice.Inject;
2720
import org.elasticsearch.tasks.Task;
2821
import org.elasticsearch.threadpool.ThreadPool;
2922
import org.elasticsearch.transport.TransportService;
30-
import org.elasticsearch.xpack.core.ilm.IndexLifecycleMetadata;
31-
import org.elasticsearch.xpack.core.ilm.LifecyclePolicyMetadata;
3223
import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction;
3324
import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction.Request;
25+
import org.elasticsearch.xpack.ilm.LifecycleMetadataService;
3426

35-
import java.util.List;
3627
import java.util.Optional;
3728
import java.util.Set;
38-
import java.util.SortedMap;
39-
import java.util.TreeMap;
40-
41-
import static org.elasticsearch.xpack.core.ilm.LifecycleOperationMetadata.currentILMMode;
4229

4330
public class TransportDeleteLifecycleAction extends TransportMasterNodeAction<Request, AcknowledgedResponse> {
4431

45-
private final ProjectResolver projectResolver;
32+
private final LifecycleMetadataService lifecycleMetadataService;
4633

4734
@Inject
4835
public TransportDeleteLifecycleAction(
4936
TransportService transportService,
5037
ClusterService clusterService,
5138
ThreadPool threadPool,
5239
ActionFilters actionFilters,
53-
ProjectResolver projectResolver
40+
LifecycleMetadataService lifecycleMetadataService
5441
) {
5542
super(
5643
DeleteLifecycleAction.NAME,
@@ -62,56 +49,12 @@ public TransportDeleteLifecycleAction(
6249
AcknowledgedResponse::readFrom,
6350
EsExecutors.DIRECT_EXECUTOR_SERVICE
6451
);
65-
this.projectResolver = projectResolver;
52+
this.lifecycleMetadataService = lifecycleMetadataService;
6653
}
6754

6855
@Override
6956
protected void masterOperation(Task task, Request request, ClusterState state, ActionListener<AcknowledgedResponse> listener) {
70-
final var projectId = projectResolver.getProjectId();
71-
submitUnbatchedTask("delete-lifecycle-" + request.getPolicyName(), new DeleteLifecyclePolicyTask(projectId, request, listener));
72-
}
73-
74-
public static class DeleteLifecyclePolicyTask extends AckedClusterStateUpdateTask {
75-
private final ProjectId projectId;
76-
private final Request request;
77-
78-
public DeleteLifecyclePolicyTask(ProjectId projectId, Request request, ActionListener<AcknowledgedResponse> listener) {
79-
super(request, listener);
80-
this.projectId = projectId;
81-
this.request = request;
82-
}
83-
84-
@Override
85-
public ClusterState execute(ClusterState currentState) {
86-
String policyToDelete = request.getPolicyName();
87-
ProjectMetadata projectMetadata = currentState.metadata().getProject(projectId);
88-
List<String> indicesUsingPolicy = projectMetadata.indices()
89-
.values()
90-
.stream()
91-
.filter(idxMeta -> policyToDelete.equals(idxMeta.getLifecyclePolicyName()))
92-
.map(idxMeta -> idxMeta.getIndex().getName())
93-
.toList();
94-
if (indicesUsingPolicy.isEmpty() == false) {
95-
throw new IllegalArgumentException(
96-
"Cannot delete policy [" + request.getPolicyName() + "]. It is in use by one or more indices: " + indicesUsingPolicy
97-
);
98-
}
99-
IndexLifecycleMetadata currentMetadata = projectMetadata.custom(IndexLifecycleMetadata.TYPE);
100-
if (currentMetadata == null || currentMetadata.getPolicyMetadatas().containsKey(request.getPolicyName()) == false) {
101-
throw new ResourceNotFoundException("Lifecycle policy not found: {}", request.getPolicyName());
102-
}
103-
SortedMap<String, LifecyclePolicyMetadata> newPolicies = new TreeMap<>(currentMetadata.getPolicyMetadatas());
104-
newPolicies.remove(request.getPolicyName());
105-
IndexLifecycleMetadata newMetadata = new IndexLifecycleMetadata(newPolicies, currentILMMode(projectMetadata));
106-
ProjectMetadata.Builder newProjectMetadata = ProjectMetadata.builder(projectMetadata)
107-
.putCustom(IndexLifecycleMetadata.TYPE, newMetadata);
108-
return ClusterState.builder(currentState).putProjectMetadata(newProjectMetadata).build();
109-
}
110-
}
111-
112-
@SuppressForbidden(reason = "legacy usage of unbatched task") // TODO add support for batching here
113-
private void submitUnbatchedTask(@SuppressWarnings("SameParameterValue") String source, ClusterStateUpdateTask task) {
114-
clusterService.submitUnbatchedStateUpdateTask(source, task);
57+
lifecycleMetadataService.deleteLifecycle(request, listener);
11558
}
11659

11760
@Override

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
package org.elasticsearch.xpack.ilm.action;
99

1010
import org.elasticsearch.action.support.ActionFilters;
11-
import org.elasticsearch.cluster.project.ProjectResolver;
1211
import org.elasticsearch.cluster.service.ClusterService;
1312
import org.elasticsearch.test.ESTestCase;
1413
import org.elasticsearch.test.MockUtils;
1514
import org.elasticsearch.threadpool.ThreadPool;
1615
import org.elasticsearch.transport.TransportService;
1716
import org.elasticsearch.xpack.core.ilm.action.DeleteLifecycleAction;
17+
import org.elasticsearch.xpack.ilm.LifecycleMetadataService;
1818

1919
import static org.hamcrest.Matchers.containsInAnyOrder;
2020
import static org.mockito.Mockito.mock;
@@ -28,7 +28,7 @@ public void testReservedStateHandler() {
2828
mock(ClusterService.class),
2929
threadPool,
3030
mock(ActionFilters.class),
31-
mock(ProjectResolver.class)
31+
mock(LifecycleMetadataService.class)
3232
);
3333
assertEquals(ReservedLifecycleAction.NAME, putAction.reservedStateHandlerName().get());
3434

0 commit comments

Comments
 (0)