-
Notifications
You must be signed in to change notification settings - Fork 25.8k
Add disabled POST _reindex/{taskId}/_cancel API
#139211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
eb32d91
Add disabled `POST _reindex/{taskId}/_cancel` API
szybia c2219a4
self-review
szybia 10bf116
fix permissions test
szybia b2bc660
use projectResolver in transport
szybia 81d455a
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 8c4b8b8
Add filtering test
szybia 1a93ff3
copilot review
szybia 904742a
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 63c1aba
move impl on-top-of `reindex-management`
szybia 3531fe7
add API spec
szybia 0df38bd
spotless
szybia f22aa74
consistent task_id > taskId
szybia 2d2c3da
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 3da0d6b
Revert "consistent task_id > taskId"
szybia 5a8f4f9
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 9c4638d
remove timeout
szybia 9b5c32d
sam comments
szybia b204b47
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 753c91d
fix after merge
szybia cd62f84
spotless
szybia 6c1daba
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 13e25c5
Pete comment to remove enum
szybia 9cf26cf
fix flaky test
szybia 39c2c66
remove dangling logger
szybia c983cb7
`s/reindex.cancel/reindex_cancel/g`
szybia 63adb15
Merge remote-tracking branch 'upstream/main' into reindex-cancel-api
szybia 7925b2f
test was still flaky...
szybia 2090620
spotless
szybia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
317 changes: 317 additions & 0 deletions
317
...nt/src/internalClusterTest/java/org/elasticsearch/reindex/management/ReindexCancelIT.java
Large diffs are not rendered by default.
Oops, something went wrong.
65 changes: 65 additions & 0 deletions
65
...x-management/src/main/java/org/elasticsearch/reindex/management/CancelReindexRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.reindex.management; | ||
|
|
||
| import org.elasticsearch.action.ActionRequestValidationException; | ||
| import org.elasticsearch.action.support.tasks.BaseTasksRequest; | ||
| import org.elasticsearch.common.io.stream.StreamInput; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.index.reindex.ReindexAction; | ||
| import org.elasticsearch.tasks.Task; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| import static org.elasticsearch.action.ValidateActions.addValidationError; | ||
|
|
||
| /** A request to cancel an ongoing reindex task. */ | ||
| public class CancelReindexRequest extends BaseTasksRequest<CancelReindexRequest> { | ||
|
|
||
| private final boolean waitForCompletion; | ||
|
|
||
| public CancelReindexRequest(StreamInput in) throws IOException { | ||
| super(in); | ||
| waitForCompletion = in.readBoolean(); | ||
| } | ||
|
|
||
| public CancelReindexRequest(boolean waitForCompletion) { | ||
| this.waitForCompletion = waitForCompletion; | ||
| } | ||
|
|
||
| @Override | ||
| public void writeTo(StreamOutput out) throws IOException { | ||
| super.writeTo(out); | ||
| out.writeBoolean(waitForCompletion); | ||
| } | ||
|
|
||
| @Override | ||
| public String getDescription() { | ||
| return "waitForCompletion[" + waitForCompletion + "], targetTaskId[" + getTargetTaskId() + "]"; | ||
| } | ||
|
|
||
| @Override | ||
| public ActionRequestValidationException validate() { | ||
| var validationException = super.validate(); | ||
| if (getTargetTaskId().isSet() == false) { | ||
| validationException = addValidationError("task id must be provided", validationException); | ||
| } | ||
| return validationException; | ||
| } | ||
|
|
||
| public boolean waitForCompletion() { | ||
| return waitForCompletion; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean match(Task task) { | ||
| return ReindexAction.NAME.equals(task.getAction()) && task.getParentTaskId().isSet() == false; | ||
| } | ||
szybia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
48 changes: 48 additions & 0 deletions
48
...-management/src/main/java/org/elasticsearch/reindex/management/CancelReindexResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.reindex.management; | ||
|
|
||
| import org.elasticsearch.action.FailedNodeException; | ||
| import org.elasticsearch.action.TaskOperationFailure; | ||
| import org.elasticsearch.action.support.tasks.BaseTasksResponse; | ||
| import org.elasticsearch.common.io.stream.StreamInput; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.xcontent.ToXContentObject; | ||
| import org.elasticsearch.xcontent.XContentBuilder; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * Response returned from {@code POST /_reindex/{taskId}/_cancel}. | ||
| */ | ||
| public class CancelReindexResponse extends BaseTasksResponse implements ToXContentObject { | ||
|
|
||
| public CancelReindexResponse(List<TaskOperationFailure> taskFailures, List<FailedNodeException> failedNodes) { | ||
| super(taskFailures, failedNodes); | ||
| } | ||
|
|
||
| public CancelReindexResponse(final StreamInput in) throws IOException { | ||
| super(in); | ||
| } | ||
|
|
||
| @Override | ||
| public void writeTo(StreamOutput out) throws IOException { | ||
| super.writeTo(out); | ||
| } | ||
|
|
||
| @Override | ||
| public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
| builder.startObject(); | ||
| builder.field("acknowledged", true); | ||
| builder.endObject(); | ||
| return builder; | ||
| } | ||
| } |
25 changes: 25 additions & 0 deletions
25
...agement/src/main/java/org/elasticsearch/reindex/management/CancelReindexTaskResponse.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.reindex.management; | ||
|
|
||
| import org.elasticsearch.common.io.stream.StreamInput; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.common.io.stream.Writeable; | ||
|
|
||
| /** Response to a single reindex task cancel action. */ | ||
| public class CancelReindexTaskResponse implements Writeable { | ||
|
|
||
| public CancelReindexTaskResponse() {} | ||
|
|
||
| public CancelReindexTaskResponse(final StreamInput in) {} | ||
|
|
||
| @Override | ||
| public void writeTo(final StreamOutput out) {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
...anagement/src/main/java/org/elasticsearch/reindex/management/RestCancelReindexAction.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.reindex.management; | ||
|
|
||
| import org.elasticsearch.client.internal.node.NodeClient; | ||
| import org.elasticsearch.features.NodeFeature; | ||
| import org.elasticsearch.rest.BaseRestHandler; | ||
| import org.elasticsearch.rest.RestRequest; | ||
| import org.elasticsearch.rest.Scope; | ||
| import org.elasticsearch.rest.ServerlessScope; | ||
| import org.elasticsearch.rest.action.RestToXContentListener; | ||
| import org.elasticsearch.tasks.TaskId; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Objects; | ||
| import java.util.function.Predicate; | ||
|
|
||
| import static org.elasticsearch.rest.RestRequest.Method.POST; | ||
|
|
||
| /** REST handler for cancelling an ongoing reindex task. */ | ||
| @ServerlessScope(Scope.PUBLIC) | ||
| public class RestCancelReindexAction extends BaseRestHandler { | ||
|
|
||
| private final Predicate<NodeFeature> clusterSupportsFeature; | ||
|
|
||
| public RestCancelReindexAction(final Predicate<NodeFeature> clusterSupportsFeature) { | ||
| this.clusterSupportsFeature = Objects.requireNonNull(clusterSupportsFeature); | ||
| } | ||
|
|
||
| @Override | ||
| public List<Route> routes() { | ||
| return List.of(new Route(POST, "/_reindex/{task_id}/_cancel")); | ||
| } | ||
|
|
||
| @Override | ||
| public String getName() { | ||
| return "cancel_reindex_action"; | ||
| } | ||
|
|
||
| @Override | ||
| protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) { | ||
| if (clusterSupportsFeature.test(ReindexManagementFeatures.NEW_ENDPOINTS) == false) { | ||
| throw new IllegalArgumentException("endpoint not supported on all nodes in the cluster"); | ||
| } | ||
| final String taskIdParam = request.param("task_id"); | ||
| final TaskId taskId = new TaskId(taskIdParam); | ||
| if (taskId.isSet() == false) { | ||
| throw new IllegalArgumentException("invalid taskId provided: " + taskIdParam); | ||
| } | ||
|
|
||
| final boolean waitForCompletion = request.paramAsBoolean("wait_for_completion", true); | ||
| final CancelReindexRequest cancelRequest = new CancelReindexRequest(waitForCompletion); | ||
| cancelRequest.setTargetTaskId(taskId); | ||
|
|
||
| return channel -> client.execute(TransportCancelReindexAction.TYPE, cancelRequest, new RestToXContentListener<>(channel)); | ||
| } | ||
| } |
113 changes: 113 additions & 0 deletions
113
...ment/src/main/java/org/elasticsearch/reindex/management/TransportCancelReindexAction.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the "Elastic License | ||
| * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| package org.elasticsearch.reindex.management; | ||
|
|
||
| import org.elasticsearch.ExceptionsHelper; | ||
| import org.elasticsearch.ResourceNotFoundException; | ||
| import org.elasticsearch.action.ActionListener; | ||
| import org.elasticsearch.action.ActionType; | ||
| import org.elasticsearch.action.FailedNodeException; | ||
| import org.elasticsearch.action.NoSuchNodeException; | ||
| import org.elasticsearch.action.TaskOperationFailure; | ||
| import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest; | ||
| import org.elasticsearch.action.support.ActionFilters; | ||
| import org.elasticsearch.action.support.tasks.TransportTasksProjectAction; | ||
| import org.elasticsearch.cluster.project.ProjectResolver; | ||
| import org.elasticsearch.cluster.service.ClusterService; | ||
| import org.elasticsearch.index.reindex.BulkByScrollTask; | ||
| import org.elasticsearch.injection.guice.Inject; | ||
| import org.elasticsearch.tasks.CancellableTask; | ||
| import org.elasticsearch.tasks.TaskId; | ||
| import org.elasticsearch.threadpool.ThreadPool; | ||
| import org.elasticsearch.transport.TransportService; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| /** Transport action that cancels an in-flight reindex task and its descendants. */ | ||
| public class TransportCancelReindexAction extends TransportTasksProjectAction< | ||
| CancellableTask, | ||
| CancelReindexRequest, | ||
| CancelReindexResponse, | ||
| CancelReindexTaskResponse> { | ||
|
|
||
| public static final ActionType<CancelReindexResponse> TYPE = new ActionType<>("cluster:admin/reindex/cancel"); | ||
|
|
||
| @Inject | ||
| public TransportCancelReindexAction( | ||
| final ClusterService clusterService, | ||
| final TransportService transportService, | ||
| final ActionFilters actionFilters, | ||
| final ProjectResolver projectResolver | ||
| ) { | ||
| super( | ||
| TYPE.name(), | ||
| clusterService, | ||
| transportService, | ||
| actionFilters, | ||
| CancelReindexRequest::new, | ||
| CancelReindexTaskResponse::new, | ||
| transportService.getThreadPool().executor(ThreadPool.Names.GENERIC), | ||
| projectResolver | ||
| ); | ||
| } | ||
|
|
||
| @Override | ||
| protected List<CancellableTask> processTasks(final CancelReindexRequest request) { | ||
| final CancellableTask requestedTask = taskManager.getCancellableTask(request.getTargetTaskId().getId()); | ||
| if (requestedTask != null && super.match(requestedTask) && request.match(requestedTask)) { | ||
| return List.of(requestedTask); | ||
| } | ||
| return List.of(); | ||
| } | ||
|
|
||
| @Override | ||
| protected void taskOperation( | ||
| final CancellableTask actionTask, | ||
| final CancelReindexRequest request, | ||
| final CancellableTask task, | ||
| final ActionListener<CancelReindexTaskResponse> listener | ||
| ) { | ||
| assert task instanceof BulkByScrollTask : "Task should be a BulkByScrollTask"; | ||
|
|
||
| taskManager.cancelTaskAndDescendants( | ||
| task, | ||
| CancelTasksRequest.DEFAULT_REASON, | ||
szybia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| request.waitForCompletion(), | ||
| ActionListener.wrap(ignored -> listener.onResponse(new CancelReindexTaskResponse()), listener::onFailure) | ||
| ); | ||
| } | ||
|
|
||
| @Override | ||
| protected CancelReindexResponse newResponse( | ||
| final CancelReindexRequest request, | ||
| final List<CancelReindexTaskResponse> tasks, | ||
| final List<TaskOperationFailure> taskFailures, | ||
| final List<FailedNodeException> nodeExceptions | ||
| ) { | ||
| assert tasks.size() + taskFailures.size() + nodeExceptions.size() <= 1 : "currently only supports cancelling one task max"; | ||
| // check whether node in requested TaskId doesn't exist and throw 404 | ||
| for (final FailedNodeException e : nodeExceptions) { | ||
| if (ExceptionsHelper.unwrap(e, NoSuchNodeException.class) != null) { | ||
| throw reindexWithTaskIdNotFoundException(request.getTargetTaskId()); | ||
| } | ||
szybia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| final var response = new CancelReindexResponse(taskFailures, nodeExceptions); | ||
| response.rethrowFailures("cancel_reindex"); // if we haven't handled any exception already, throw here | ||
szybia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (tasks.isEmpty()) { | ||
| throw reindexWithTaskIdNotFoundException(request.getTargetTaskId()); | ||
| } | ||
| return response; | ||
| } | ||
|
|
||
| private static ResourceNotFoundException reindexWithTaskIdNotFoundException(final TaskId requestedTaskId) { | ||
| return new ResourceNotFoundException("reindex task [{}] either not found or completed", requestedTaskId); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.