Fix trappy timeouts in persistent tasks requests (#120514)

Ensure that callers constructing these master-node requests pass in an
explicit timeout.

Relates #107984
This commit is contained in:
David Turner 2025-01-23 09:35:45 +00:00 committed by GitHub
parent 7563e71e90
commit a1fd7bc374
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 188 additions and 111 deletions

View file

@ -113,7 +113,7 @@ public class PersistentTaskCreationFailureIT extends ESIntegTestCase {
UUIDs.base64UUID(), UUIDs.base64UUID(),
FailingCreationPersistentTaskExecutor.TASK_NAME, FailingCreationPersistentTaskExecutor.TASK_NAME,
new FailingCreationTaskParams(), new FailingCreationTaskParams(),
null, TEST_REQUEST_TIMEOUT,
l.map(ignored -> null) l.map(ignored -> null)
) )
); );

View file

@ -50,7 +50,7 @@ public class PersistentTaskInitializationFailureIT extends ESIntegTestCase {
UUIDs.base64UUID(), UUIDs.base64UUID(),
FailingInitializationPersistentTaskExecutor.TASK_NAME, FailingInitializationPersistentTaskExecutor.TASK_NAME,
new FailingInitializationTaskParams(), new FailingInitializationTaskParams(),
null, TEST_REQUEST_TIMEOUT,
startPersistentTaskFuture startPersistentTaskFuture
); );
startPersistentTaskFuture.actionGet(); startPersistentTaskFuture.actionGet();

View file

@ -45,7 +45,7 @@ public class PersistentTasksExecutorFullRestartIT extends ESIntegTestCase {
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
futures.add(future); futures.add(future);
taskIds[i] = UUIDs.base64UUID(); taskIds[i] = UUIDs.base64UUID();
service.sendStartRequest(taskIds[i], TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future); service.sendStartRequest(taskIds[i], TestPersistentTasksExecutor.NAME, new TestParams("Blah"), TEST_REQUEST_TIMEOUT, future);
} }
for (int i = 0; i < numberOfTasks; i++) { for (int i = 0; i < numberOfTasks; i++) {

View file

@ -69,7 +69,13 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
public void testPersistentActionFailure() throws Exception { public void testPersistentActionFailure() throws Exception {
PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class); PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class);
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
persistentTasksService.sendStartRequest(UUIDs.base64UUID(), TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future); persistentTasksService.sendStartRequest(
UUIDs.base64UUID(),
TestPersistentTasksExecutor.NAME,
new TestParams("Blah"),
TEST_REQUEST_TIMEOUT,
future
);
long allocationId = future.get().getAllocationId(); long allocationId = future.get().getAllocationId();
waitForTaskToStart(); waitForTaskToStart();
TaskInfo firstRunningTask = clusterAdmin().prepareListTasks() TaskInfo firstRunningTask = clusterAdmin().prepareListTasks()
@ -100,7 +106,13 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class); PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class);
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
String taskId = UUIDs.base64UUID(); String taskId = UUIDs.base64UUID();
persistentTasksService.sendStartRequest(taskId, TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future); persistentTasksService.sendStartRequest(
taskId,
TestPersistentTasksExecutor.NAME,
new TestParams("Blah"),
TEST_REQUEST_TIMEOUT,
future
);
long allocationId = future.get().getAllocationId(); long allocationId = future.get().getAllocationId();
waitForTaskToStart(); waitForTaskToStart();
TaskInfo firstRunningTask = clusterAdmin().prepareListTasks() TaskInfo firstRunningTask = clusterAdmin().prepareListTasks()
@ -119,7 +131,14 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
logger.info("Simulating errant completion notification"); logger.info("Simulating errant completion notification");
// try sending completion request with incorrect allocation id // try sending completion request with incorrect allocation id
PlainActionFuture<PersistentTask<?>> failedCompletionNotificationFuture = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<?>> failedCompletionNotificationFuture = new PlainActionFuture<>();
persistentTasksService.sendCompletionRequest(taskId, Long.MAX_VALUE, null, null, null, failedCompletionNotificationFuture); persistentTasksService.sendCompletionRequest(
taskId,
Long.MAX_VALUE,
null,
null,
TEST_REQUEST_TIMEOUT,
failedCompletionNotificationFuture
);
assertFutureThrows(failedCompletionNotificationFuture, ResourceNotFoundException.class); assertFutureThrows(failedCompletionNotificationFuture, ResourceNotFoundException.class);
// Make sure that the task is still running // Make sure that the task is still running
assertThat( assertThat(
@ -141,7 +160,13 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
TestParams testParams = new TestParams("Blah"); TestParams testParams = new TestParams("Blah");
testParams.setExecutorNodeAttr("test"); testParams.setExecutorNodeAttr("test");
persistentTasksService.sendStartRequest(UUIDs.base64UUID(), TestPersistentTasksExecutor.NAME, testParams, null, future); persistentTasksService.sendStartRequest(
UUIDs.base64UUID(),
TestPersistentTasksExecutor.NAME,
testParams,
TEST_REQUEST_TIMEOUT,
future
);
String taskId = future.get().getId(); String taskId = future.get().getId();
Settings nodeSettings = Settings.builder().put(nodeSettings(0, Settings.EMPTY)).put("node.attr.test_attr", "test").build(); Settings nodeSettings = Settings.builder().put(nodeSettings(0, Settings.EMPTY)).put("node.attr.test_attr", "test").build();
@ -165,7 +190,7 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
// Remove the persistent task // Remove the persistent task
PlainActionFuture<PersistentTask<?>> removeFuture = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<?>> removeFuture = new PlainActionFuture<>();
persistentTasksService.sendRemoveRequest(taskId, null, removeFuture); persistentTasksService.sendRemoveRequest(taskId, TEST_REQUEST_TIMEOUT, removeFuture);
assertEquals(removeFuture.get().getId(), taskId); assertEquals(removeFuture.get().getId(), taskId);
} }
@ -182,7 +207,13 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class); PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class);
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
TestParams testParams = new TestParams("Blah"); TestParams testParams = new TestParams("Blah");
persistentTasksService.sendStartRequest(UUIDs.base64UUID(), TestPersistentTasksExecutor.NAME, testParams, null, future); persistentTasksService.sendStartRequest(
UUIDs.base64UUID(),
TestPersistentTasksExecutor.NAME,
testParams,
TEST_REQUEST_TIMEOUT,
future
);
String taskId = future.get().getId(); String taskId = future.get().getId();
assertThat(clusterAdmin().prepareListTasks().setActions(TestPersistentTasksExecutor.NAME + "[c]").get().getTasks(), empty()); assertThat(clusterAdmin().prepareListTasks().setActions(TestPersistentTasksExecutor.NAME + "[c]").get().getTasks(), empty());
@ -197,14 +228,20 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
// Remove the persistent task // Remove the persistent task
PlainActionFuture<PersistentTask<?>> removeFuture = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<?>> removeFuture = new PlainActionFuture<>();
persistentTasksService.sendRemoveRequest(taskId, null, removeFuture); persistentTasksService.sendRemoveRequest(taskId, TEST_REQUEST_TIMEOUT, removeFuture);
assertEquals(removeFuture.get().getId(), taskId); assertEquals(removeFuture.get().getId(), taskId);
} }
public void testPersistentActionStatusUpdate() throws Exception { public void testPersistentActionStatusUpdate() throws Exception {
PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class); PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class);
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
persistentTasksService.sendStartRequest(UUIDs.base64UUID(), TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future); persistentTasksService.sendStartRequest(
UUIDs.base64UUID(),
TestPersistentTasksExecutor.NAME,
new TestParams("Blah"),
TEST_REQUEST_TIMEOUT,
future
);
String taskId = future.get().getId(); String taskId = future.get().getId();
waitForTaskToStart(); waitForTaskToStart();
TaskInfo firstRunningTask = clusterAdmin().prepareListTasks() TaskInfo firstRunningTask = clusterAdmin().prepareListTasks()
@ -250,7 +287,7 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
assertFutureThrows(future1, IllegalStateException.class, "timed out after 10ms"); assertFutureThrows(future1, IllegalStateException.class, "timed out after 10ms");
PlainActionFuture<PersistentTask<?>> failedUpdateFuture = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<?>> failedUpdateFuture = new PlainActionFuture<>();
persistentTasksService.sendUpdateStateRequest(taskId, -2, new State("should fail"), null, failedUpdateFuture); persistentTasksService.sendUpdateStateRequest(taskId, -2, new State("should fail"), TEST_REQUEST_TIMEOUT, failedUpdateFuture);
assertFutureThrows( assertFutureThrows(
failedUpdateFuture, failedUpdateFuture,
ResourceNotFoundException.class, ResourceNotFoundException.class,
@ -275,11 +312,23 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class); PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class);
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
String taskId = UUIDs.base64UUID(); String taskId = UUIDs.base64UUID();
persistentTasksService.sendStartRequest(taskId, TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future); persistentTasksService.sendStartRequest(
taskId,
TestPersistentTasksExecutor.NAME,
new TestParams("Blah"),
TEST_REQUEST_TIMEOUT,
future
);
future.get(); future.get();
PlainActionFuture<PersistentTask<TestParams>> future2 = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future2 = new PlainActionFuture<>();
persistentTasksService.sendStartRequest(taskId, TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future2); persistentTasksService.sendStartRequest(
taskId,
TestPersistentTasksExecutor.NAME,
new TestParams("Blah"),
TEST_REQUEST_TIMEOUT,
future2
);
assertFutureThrows(future2, ResourceAlreadyExistsException.class); assertFutureThrows(future2, ResourceAlreadyExistsException.class);
waitForTaskToStart(); waitForTaskToStart();
@ -315,7 +364,13 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
TestParams testParams = new TestParams("Blah"); TestParams testParams = new TestParams("Blah");
testParams.setExecutorNodeAttr("test"); testParams.setExecutorNodeAttr("test");
persistentTasksService.sendStartRequest(UUIDs.base64UUID(), TestPersistentTasksExecutor.NAME, testParams, null, future); persistentTasksService.sendStartRequest(
UUIDs.base64UUID(),
TestPersistentTasksExecutor.NAME,
testParams,
TEST_REQUEST_TIMEOUT,
future
);
PersistentTask<TestParams> task = future.get(); PersistentTask<TestParams> task = future.get();
String taskId = task.getId(); String taskId = task.getId();
@ -366,7 +421,13 @@ public class PersistentTasksExecutorIT extends ESIntegTestCase {
persistentTasksClusterService.setRecheckInterval(TimeValue.timeValueMillis(1)); persistentTasksClusterService.setRecheckInterval(TimeValue.timeValueMillis(1));
PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class); PersistentTasksService persistentTasksService = internalCluster().getInstance(PersistentTasksService.class);
PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>(); PlainActionFuture<PersistentTask<TestParams>> future = new PlainActionFuture<>();
persistentTasksService.sendStartRequest(UUIDs.base64UUID(), TestPersistentTasksExecutor.NAME, new TestParams("Blah"), null, future); persistentTasksService.sendStartRequest(
UUIDs.base64UUID(),
TestPersistentTasksExecutor.NAME,
new TestParams("Blah"),
TEST_REQUEST_TIMEOUT,
future
);
String taskId = future.get().getId(); String taskId = future.get().getId();
long allocationId = future.get().getAllocationId(); long allocationId = future.get().getAllocationId();
waitForTaskToStart(); waitForTaskToStart();

View file

@ -52,7 +52,7 @@ public class EnableAssignmentDeciderIT extends ESIntegTestCase {
"task_" + i, "task_" + i,
TestPersistentTasksExecutor.NAME, TestPersistentTasksExecutor.NAME,
new TestParams(randomAlphaOfLength(10)), new TestParams(randomAlphaOfLength(10)),
null, TEST_REQUEST_TIMEOUT,
ActionListener.running(latch::countDown) ActionListener.running(latch::countDown)
); );
} }

View file

@ -21,6 +21,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.indices.SystemIndices; import org.elasticsearch.indices.SystemIndices;
import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.persistent.PersistentTasksService; import org.elasticsearch.persistent.PersistentTasksService;
@ -95,7 +96,7 @@ public class TransportPostFeatureUpgradeAction extends TransportMasterNodeAction
SYSTEM_INDEX_UPGRADE_TASK_NAME, SYSTEM_INDEX_UPGRADE_TASK_NAME,
SYSTEM_INDEX_UPGRADE_TASK_NAME, SYSTEM_INDEX_UPGRADE_TASK_NAME,
new SystemIndexMigrationTaskParams(), new SystemIndexMigrationTaskParams(),
null, TimeValue.THIRTY_SECONDS /* TODO should this be configurable? longer by default? infinite? */,
ActionListener.wrap(startedTask -> { ActionListener.wrap(startedTask -> {
listener.onResponse(new PostFeatureUpgradeResponse(true, featuresToMigrate, null, null)); listener.onResponse(new PostFeatureUpgradeResponse(true, featuresToMigrate, null, null));
}, ex -> { }, ex -> {

View file

@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.features.FeatureService; import org.elasticsearch.features.FeatureService;
import org.elasticsearch.node.NodeClosedException; import org.elasticsearch.node.NodeClosedException;
import org.elasticsearch.persistent.AllocatedPersistentTask; import org.elasticsearch.persistent.AllocatedPersistentTask;
@ -162,7 +163,7 @@ public final class HealthNodeTaskExecutor extends PersistentTasksExecutor<Health
TASK_NAME, TASK_NAME,
TASK_NAME, TASK_NAME,
new HealthNodeTaskParams(), new HealthNodeTaskParams(),
null, TimeValue.THIRTY_SECONDS /* TODO should this be configurable? longer by default? infinite? */,
ActionListener.wrap(r -> logger.debug("Created the health node task"), e -> { ActionListener.wrap(r -> logger.debug("Created the health node task"), e -> {
if (e instanceof NodeClosedException) { if (e instanceof NodeClosedException) {
logger.debug("Failed to create health node task because node is shutting down", e); logger.debug("Failed to create health node task because node is shutting down", e);

View file

@ -65,7 +65,13 @@ public class AllocatedPersistentTask extends CancellableTask {
final PersistentTaskState state, final PersistentTaskState state,
final ActionListener<PersistentTasksCustomMetadata.PersistentTask<?>> listener final ActionListener<PersistentTasksCustomMetadata.PersistentTask<?>> listener
) { ) {
persistentTasksService.sendUpdateStateRequest(persistentTaskId, allocationId, state, null, listener); persistentTasksService.sendUpdateStateRequest(
persistentTaskId,
allocationId,
state,
TimeValue.THIRTY_SECONDS /* TODO should this be longer? infinite? */,
listener
);
} }
public String getPersistentTaskId() { public String getPersistentTaskId() {
@ -201,7 +207,7 @@ public class AllocatedPersistentTask extends CancellableTask {
getAllocationId(), getAllocationId(),
failure, failure,
localAbortReason, localAbortReason,
null, TimeValue.THIRTY_SECONDS /* TODO should this be longer? infinite? */,
new ActionListener<>() { new ActionListener<>() {
@Override @Override
public void onResponse(PersistentTasksCustomMetadata.PersistentTask<?> persistentTask) { public void onResponse(PersistentTasksCustomMetadata.PersistentTask<?> persistentTask) {

View file

@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -56,8 +57,8 @@ public class CompletionPersistentTaskAction {
localAbortReason = in.readOptionalString(); localAbortReason = in.readOptionalString();
} }
public Request(String taskId, long allocationId, Exception exception, String localAbortReason) { public Request(TimeValue masterNodeTimeout, String taskId, long allocationId, Exception exception, String localAbortReason) {
super(TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT); super(masterNodeTimeout);
this.taskId = taskId; this.taskId = taskId;
this.exception = exception; this.exception = exception;
this.allocationId = allocationId; this.allocationId = allocationId;

View file

@ -18,6 +18,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.gateway.GatewayService; import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.persistent.PersistentTasksCustomMetadata.PersistentTask; import org.elasticsearch.persistent.PersistentTasksCustomMetadata.PersistentTask;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
@ -310,7 +311,7 @@ public class PersistentTasksNodeService implements ClusterStateListener {
taskInProgress.getAllocationId(), taskInProgress.getAllocationId(),
originalException, originalException,
null, null,
null, TimeValue.THIRTY_SECONDS /* TODO should this be longer? infinite? */,
new ActionListener<>() { new ActionListener<>() {
@Override @Override
public void onResponse(PersistentTask<?> persistentTask) { public void onResponse(PersistentTask<?> persistentTask) {
@ -346,7 +347,7 @@ public class PersistentTasksNodeService implements ClusterStateListener {
if (task.markAsCancelled()) { if (task.markAsCancelled()) {
// Cancel the local task using the task manager // Cancel the local task using the task manager
String reason = "task has been removed, cancelling locally"; String reason = "task has been removed, cancelling locally";
persistentTasksService.sendCancelRequest(task.getId(), reason, null, new ActionListener<>() { persistentTasksService.sendCancelRequest(task.getId(), reason, new ActionListener<>() {
@Override @Override
public void onResponse(ListTasksResponse cancelTasksResponse) { public void onResponse(ListTasksResponse cancelTasksResponse) {
logger.trace( logger.trace(

View file

@ -27,6 +27,7 @@ import org.elasticsearch.persistent.PersistentTasksCustomMetadata.PersistentTask
import org.elasticsearch.tasks.TaskId; import org.elasticsearch.tasks.TaskId;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import java.util.Objects;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
@ -57,16 +58,16 @@ public class PersistentTasksService {
final String taskId, final String taskId,
final String taskName, final String taskName,
final Params taskParams, final Params taskParams,
final @Nullable TimeValue timeout, final TimeValue timeout,
final ActionListener<PersistentTask<Params>> listener final ActionListener<PersistentTask<Params>> listener
) { ) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final ActionListener<PersistentTask<?>> wrappedListener = listener.map(t -> (PersistentTask<Params>) t); final ActionListener<PersistentTask<?>> wrappedListener = listener.map(t -> (PersistentTask<Params>) t);
StartPersistentTaskAction.Request request = new StartPersistentTaskAction.Request(taskId, taskName, taskParams); execute(
if (timeout != null) { new StartPersistentTaskAction.Request(Objects.requireNonNull(timeout), taskId, taskName, taskParams),
request.masterNodeTimeout(timeout); StartPersistentTaskAction.INSTANCE,
} wrappedListener
execute(request, StartPersistentTaskAction.INSTANCE, wrappedListener); );
} }
/** /**
@ -85,33 +86,27 @@ public class PersistentTasksService {
final @Nullable TimeValue timeout, final @Nullable TimeValue timeout,
final ActionListener<PersistentTask<?>> listener final ActionListener<PersistentTask<?>> listener
) { ) {
CompletionPersistentTaskAction.Request request = new CompletionPersistentTaskAction.Request( execute(
new CompletionPersistentTaskAction.Request(
Objects.requireNonNull(timeout),
taskId, taskId,
taskAllocationId, taskAllocationId,
taskFailure, taskFailure,
localAbortReason localAbortReason
),
CompletionPersistentTaskAction.INSTANCE,
listener
); );
if (timeout != null) {
request.masterNodeTimeout(timeout);
}
execute(request, CompletionPersistentTaskAction.INSTANCE, listener);
} }
/** /**
* Cancels a locally running task using the Task Manager API. Accepts operation timeout as optional parameter * Cancels a locally running task using the Task Manager API. Accepts operation timeout as optional parameter
*/ */
void sendCancelRequest( void sendCancelRequest(final long taskId, final String reason, final ActionListener<ListTasksResponse> listener) {
final long taskId,
final String reason,
final @Nullable TimeValue timeout,
final ActionListener<ListTasksResponse> listener
) {
CancelTasksRequest request = new CancelTasksRequest(); CancelTasksRequest request = new CancelTasksRequest();
request.setTargetTaskId(new TaskId(clusterService.localNode().getId(), taskId)); request.setTargetTaskId(new TaskId(clusterService.localNode().getId(), taskId));
request.setReason(reason); request.setReason(reason);
if (timeout != null) { // TODO set timeout?
request.setTimeout(timeout);
}
try { try {
client.admin().cluster().cancelTasks(request, listener); client.admin().cluster().cancelTasks(request, listener);
} catch (Exception e) { } catch (Exception e) {
@ -130,33 +125,25 @@ public class PersistentTasksService {
final String taskId, final String taskId,
final long taskAllocationID, final long taskAllocationID,
final PersistentTaskState taskState, final PersistentTaskState taskState,
final @Nullable TimeValue timeout, final TimeValue timeout,
final ActionListener<PersistentTask<?>> listener final ActionListener<PersistentTask<?>> listener
) { ) {
UpdatePersistentTaskStatusAction.Request request = new UpdatePersistentTaskStatusAction.Request( execute(
taskId, new UpdatePersistentTaskStatusAction.Request(Objects.requireNonNull(timeout), taskId, taskAllocationID, taskState),
taskAllocationID, UpdatePersistentTaskStatusAction.INSTANCE,
taskState listener
); );
if (timeout != null) {
request.masterNodeTimeout(timeout);
}
execute(request, UpdatePersistentTaskStatusAction.INSTANCE, listener);
} }
/** /**
* Notifies the master node to remove a persistent task from the cluster state. Accepts operation timeout as optional parameter * Notifies the master node to remove a persistent task from the cluster state. Accepts operation timeout as optional parameter
*/ */
public void sendRemoveRequest( public void sendRemoveRequest(final String taskId, final TimeValue timeout, final ActionListener<PersistentTask<?>> listener) {
final String taskId, execute(
final @Nullable TimeValue timeout, new RemovePersistentTaskAction.Request(Objects.requireNonNull(timeout), taskId),
final ActionListener<PersistentTask<?>> listener RemovePersistentTaskAction.INSTANCE,
) { listener
RemovePersistentTaskAction.Request request = new RemovePersistentTaskAction.Request(taskId); );
if (timeout != null) {
request.masterNodeTimeout(timeout);
}
execute(request, RemovePersistentTaskAction.INSTANCE, listener);
} }
/** /**

View file

@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -44,8 +45,8 @@ public class RemovePersistentTaskAction {
taskId = in.readString(); taskId = in.readString();
} }
public Request(String taskId) { public Request(TimeValue masterNodeTimeout, String taskId) {
super(TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT); super(masterNodeTimeout);
this.taskId = taskId; this.taskId = taskId;
} }

View file

@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -52,8 +53,8 @@ public class StartPersistentTaskAction {
params = in.readNamedWriteable(PersistentTaskParams.class); params = in.readNamedWriteable(PersistentTaskParams.class);
} }
public Request(String taskId, String taskName, PersistentTaskParams params) { public Request(TimeValue masterNodeTimeout, String taskId, String taskName, PersistentTaskParams params) {
super(TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT); super(masterNodeTimeout);
this.taskId = taskId; this.taskId = taskId;
this.taskName = taskName; this.taskName = taskName;
this.params = params; this.params = params;

View file

@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -49,8 +50,8 @@ public class UpdatePersistentTaskStatusAction {
state = in.readOptionalNamedWriteable(PersistentTaskState.class); state = in.readOptionalNamedWriteable(PersistentTaskState.class);
} }
public Request(String taskId, long allocationId, PersistentTaskState state) { public Request(TimeValue masterNodeTimeout, String taskId, long allocationId, PersistentTaskState state) {
super(TRAPPY_IMPLICIT_DEFAULT_MASTER_NODE_TIMEOUT); super(masterNodeTimeout);
this.taskId = taskId; this.taskId = taskId;
this.allocationId = allocationId; this.allocationId = allocationId;
this.state = state; this.state = state;

View file

@ -42,6 +42,7 @@ import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@ -102,7 +103,7 @@ public class HealthNodeTaskExecutorTests extends ESTestCase {
eq("health-node"), eq("health-node"),
eq("health-node"), eq("health-node"),
eq(new HealthNodeTaskParams()), eq(new HealthNodeTaskParams()),
eq(null), isNotNull(),
any() any()
) )
); );
@ -121,7 +122,7 @@ public class HealthNodeTaskExecutorTests extends ESTestCase {
eq("health-node"), eq("health-node"),
eq("health-node"), eq("health-node"),
eq(new HealthNodeTaskParams()), eq(new HealthNodeTaskParams()),
eq(null), isNotNull(),
any() any()
); );
} }

View file

@ -18,7 +18,7 @@ public class CancelPersistentTaskRequestTests extends AbstractWireSerializingTes
@Override @Override
protected Request createTestInstance() { protected Request createTestInstance() {
return new Request(randomAsciiOfLength(10)); return new Request(randomTimeValue(), randomAsciiOfLength(10));
} }
@Override @Override

View file

@ -17,9 +17,9 @@ public class CompletionPersistentTaskRequestTests extends AbstractWireSerializin
@Override @Override
protected Request createTestInstance() { protected Request createTestInstance() {
if (randomBoolean()) { if (randomBoolean()) {
return new Request(randomAlphaOfLength(10), randomNonNegativeLong(), null, null); return new Request(randomTimeValue(), randomAlphaOfLength(10), randomNonNegativeLong(), null, null);
} else { } else {
return new Request(randomAlphaOfLength(10), randomNonNegativeLong(), null, randomAlphaOfLength(20)); return new Request(randomTimeValue(), randomAlphaOfLength(10), randomNonNegativeLong(), null, randomAlphaOfLength(20));
} }
} }

View file

@ -260,12 +260,7 @@ public class PersistentTasksNodeServiceTests extends ESTestCase {
when(client.settings()).thenReturn(Settings.EMPTY); when(client.settings()).thenReturn(Settings.EMPTY);
PersistentTasksService persistentTasksService = new PersistentTasksService(null, null, client) { PersistentTasksService persistentTasksService = new PersistentTasksService(null, null, client) {
@Override @Override
void sendCancelRequest( void sendCancelRequest(final long taskId, final String reason, final ActionListener<ListTasksResponse> listener) {
final long taskId,
final String reason,
final TimeValue timeout,
final ActionListener<ListTasksResponse> listener
) {
capturedTaskId.set(taskId); capturedTaskId.set(taskId);
capturedListener.set(listener); capturedListener.set(listener);
} }
@ -356,12 +351,7 @@ public class PersistentTasksNodeServiceTests extends ESTestCase {
when(client.settings()).thenReturn(Settings.EMPTY); when(client.settings()).thenReturn(Settings.EMPTY);
PersistentTasksService persistentTasksService = new PersistentTasksService(null, null, client) { PersistentTasksService persistentTasksService = new PersistentTasksService(null, null, client) {
@Override @Override
void sendCancelRequest( void sendCancelRequest(final long taskId, final String reason, final ActionListener<ListTasksResponse> listener) {
final long taskId,
final String reason,
final TimeValue timeout,
final ActionListener<ListTasksResponse> listener
) {
fail("Shouldn't be called during local abort"); fail("Shouldn't be called during local abort");
} }

View file

@ -30,7 +30,7 @@ public class StartPersistentActionRequestTests extends AbstractWireSerializingTe
if (randomBoolean()) { if (randomBoolean()) {
testParams.setExecutorNodeAttr(randomAlphaOfLengthBetween(1, 20)); testParams.setExecutorNodeAttr(randomAlphaOfLengthBetween(1, 20));
} }
return new Request(UUIDs.base64UUID(), randomAlphaOfLengthBetween(1, 20), testParams); return new Request(randomTimeValue(), UUIDs.base64UUID(), randomAlphaOfLengthBetween(1, 20), testParams);
} }
@Override @Override

View file

@ -22,7 +22,7 @@ public class UpdatePersistentTaskRequestTests extends AbstractWireSerializingTes
@Override @Override
protected Request createTestInstance() { protected Request createTestInstance() {
return new Request(UUIDs.base64UUID(), randomLong(), new State(randomAlphaOfLength(10))); return new Request(randomTimeValue(), UUIDs.base64UUID(), randomLong(), new State(randomAlphaOfLength(10)));
} }
@Override @Override

View file

@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.ActionRunnable;
import org.elasticsearch.action.support.master.MasterNodeRequest;
import org.elasticsearch.client.internal.Client; import org.elasticsearch.client.internal.Client;
import org.elasticsearch.cluster.ClusterChangedEvent; import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterStateListener; import org.elasticsearch.cluster.ClusterStateListener;
@ -110,6 +111,7 @@ public final class ShardFollowTaskCleaner implements ClusterStateListener {
client.execute( client.execute(
CompletionPersistentTaskAction.INSTANCE, CompletionPersistentTaskAction.INSTANCE,
new CompletionPersistentTaskAction.Request( new CompletionPersistentTaskAction.Request(
MasterNodeRequest.INFINITE_MASTER_NODE_TIMEOUT,
persistentTask.getId(), persistentTask.getId(),
persistentTask.getAllocationId(), persistentTask.getAllocationId(),
new IndexNotFoundException(followerIndex), new IndexNotFoundException(followerIndex),

View file

@ -549,7 +549,7 @@ public class TransportDownsampleAction extends AcknowledgedTransportMasterNodeAc
persistentTaskId, persistentTaskId,
DownsampleShardTask.TASK_NAME, DownsampleShardTask.TASK_NAME,
params, params,
null, TimeValue.THIRTY_SECONDS /* TODO should this be configurable? longer by default? infinite? */,
ActionListener.wrap( ActionListener.wrap(
startedTask -> persistentTasksService.waitForPersistentTaskCondition( startedTask -> persistentTasksService.waitForPersistentTaskCondition(
startedTask.getId(), startedTask.getId(),

View file

@ -16,6 +16,7 @@ import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.cluster.metadata.DataStream; import org.elasticsearch.cluster.metadata.DataStream;
import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.injection.guice.Inject;
import org.elasticsearch.persistent.PersistentTasksService; import org.elasticsearch.persistent.PersistentTasksService;
import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.Task;
@ -81,7 +82,7 @@ public class ReindexDataStreamTransportAction extends HandledTransportAction<Rei
persistentTaskId, persistentTaskId,
ReindexDataStreamTask.TASK_NAME, ReindexDataStreamTask.TASK_NAME,
params, params,
null, TimeValue.THIRTY_SECONDS /* TODO should this be configurable? longer by default? infinite? */,
ActionListener.wrap(startedTask -> listener.onResponse(AcknowledgedResponse.TRUE), listener::onFailure) ActionListener.wrap(startedTask -> listener.onResponse(AcknowledgedResponse.TRUE), listener::onFailure)
); );
} }

View file

@ -308,6 +308,7 @@ public class MlDistributedFailureIT extends BaseMlIntegTestCase {
} }
UpdatePersistentTaskStatusAction.Request updatePersistentTaskStatusRequest = new UpdatePersistentTaskStatusAction.Request( UpdatePersistentTaskStatusAction.Request updatePersistentTaskStatusRequest = new UpdatePersistentTaskStatusAction.Request(
TEST_REQUEST_TIMEOUT,
task.getId(), task.getId(),
task.getAllocationId(), task.getAllocationId(),
DatafeedState.STOPPING DatafeedState.STOPPING

View file

@ -322,7 +322,7 @@ public class TransportPutRollupJobAction extends AcknowledgedTransportMasterNode
job.getConfig().getId(), job.getConfig().getId(),
RollupField.TASK_NAME, RollupField.TASK_NAME,
job, job,
null, TimeValue.THIRTY_SECONDS /* TODO should this be configurable? longer by default? infinite? */,
ActionListener.wrap(rollupConfigPersistentTask -> waitForRollupStarted(job, listener, persistentTasksService), e -> { ActionListener.wrap(rollupConfigPersistentTask -> waitForRollupStarted(job, listener, persistentTasksService), e -> {
if (e instanceof ResourceAlreadyExistsException) { if (e instanceof ResourceAlreadyExistsException) {
e = new ElasticsearchStatusException( e = new ElasticsearchStatusException(

View file

@ -42,6 +42,7 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -373,10 +374,10 @@ public class PutJobStateMachineTests extends ESTestCase {
requestCaptor.getValue().onFailure(new ResourceAlreadyExistsException(job.getConfig().getRollupIndex())); requestCaptor.getValue().onFailure(new ResourceAlreadyExistsException(job.getConfig().getRollupIndex()));
return null; return null;
}).when(tasksService) }).when(tasksService)
.sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), eq(null), requestCaptor.capture()); .sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), isNotNull(), requestCaptor.capture());
TransportPutRollupJobAction.startPersistentTask(job, testListener, tasksService); TransportPutRollupJobAction.startPersistentTask(job, testListener, tasksService);
verify(tasksService).sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), eq(null), any()); verify(tasksService).sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), isNotNull(), any());
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@ -401,7 +402,7 @@ public class PutJobStateMachineTests extends ESTestCase {
requestCaptor.getValue().onResponse(response); requestCaptor.getValue().onResponse(response);
return null; return null;
}).when(tasksService) }).when(tasksService)
.sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), eq(null), requestCaptor.capture()); .sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), isNotNull(), requestCaptor.capture());
ArgumentCaptor<PersistentTasksService.WaitForPersistentTaskListener> requestCaptor2 = ArgumentCaptor.forClass( ArgumentCaptor<PersistentTasksService.WaitForPersistentTaskListener> requestCaptor2 = ArgumentCaptor.forClass(
PersistentTasksService.WaitForPersistentTaskListener.class PersistentTasksService.WaitForPersistentTaskListener.class
@ -413,7 +414,7 @@ public class PutJobStateMachineTests extends ESTestCase {
}).when(tasksService).waitForPersistentTaskCondition(eq(job.getConfig().getId()), any(), any(), requestCaptor2.capture()); }).when(tasksService).waitForPersistentTaskCondition(eq(job.getConfig().getId()), any(), any(), requestCaptor2.capture());
TransportPutRollupJobAction.startPersistentTask(job, testListener, tasksService); TransportPutRollupJobAction.startPersistentTask(job, testListener, tasksService);
verify(tasksService).sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), eq(null), any()); verify(tasksService).sendStartRequest(eq(job.getConfig().getId()), eq(RollupField.TASK_NAME), eq(job), isNotNull(), any());
verify(tasksService).waitForPersistentTaskCondition(eq(job.getConfig().getId()), any(), any(), any()); verify(tasksService).waitForPersistentTaskCondition(eq(job.getConfig().getId()), any(), any(), any());
} }

View file

@ -63,6 +63,7 @@ import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.core.IOUtils; import org.elasticsearch.core.IOUtils;
import org.elasticsearch.core.Nullable; import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.Releasable; import org.elasticsearch.core.Releasable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.env.NodeMetadata; import org.elasticsearch.env.NodeMetadata;
import org.elasticsearch.features.FeatureService; import org.elasticsearch.features.FeatureService;
@ -1273,7 +1274,7 @@ public class Security extends Plugin
SecurityMigrationTaskParams.TASK_NAME, SecurityMigrationTaskParams.TASK_NAME,
SecurityMigrationTaskParams.TASK_NAME, SecurityMigrationTaskParams.TASK_NAME,
new SecurityMigrationTaskParams(migrationsVersion, securityMigrationNeeded), new SecurityMigrationTaskParams(migrationsVersion, securityMigrationNeeded),
null, TimeValue.THIRTY_SECONDS /* TODO should this be configurable? longer by default? infinite? */,
ActionListener.wrap((response) -> { ActionListener.wrap((response) -> {
logger.debug("Security migration task submitted"); logger.debug("Security migration task submitted");
}, (exception) -> { }, (exception) -> {

View file

@ -183,12 +183,18 @@ public class NodeShutdownTasksIT extends ESIntegTestCase {
private void startTask() { private void startTask() {
logger.info("--> sending start request"); logger.info("--> sending start request");
persistentTasksService.sendStartRequest("task_id", "task_name", new TestTaskParams(), null, ActionListener.wrap(r -> {}, e -> { persistentTasksService.sendStartRequest(
"task_id",
"task_name",
new TestTaskParams(),
TEST_REQUEST_TIMEOUT,
ActionListener.wrap(r -> {}, e -> {
if (e instanceof ResourceAlreadyExistsException == false) { if (e instanceof ResourceAlreadyExistsException == false) {
logger.error("failed to create task", e); logger.error("failed to create task", e);
fail("failed to create task"); fail("failed to create task");
} }
})); })
);
} }
@Override @Override

View file

@ -266,11 +266,23 @@ public class TransportStopTransformActionTests extends ESTestCase {
when(client.threadPool()).thenReturn(threadPool); when(client.threadPool()).thenReturn(threadPool);
doAnswer(randomBoolean() ? withResponse() : withException(new ResourceNotFoundException("task not found"))).when(client) doAnswer(randomBoolean() ? withResponse() : withException(new ResourceNotFoundException("task not found"))).when(client)
.execute(same(RemovePersistentTaskAction.INSTANCE), eq(new RemovePersistentTaskAction.Request("task-A")), any()); .execute(
same(RemovePersistentTaskAction.INSTANCE),
eq(new RemovePersistentTaskAction.Request(TEST_REQUEST_TIMEOUT, "task-A")),
any()
);
doAnswer(randomBoolean() ? withResponse() : withException(new ResourceNotFoundException("task not found"))).when(client) doAnswer(randomBoolean() ? withResponse() : withException(new ResourceNotFoundException("task not found"))).when(client)
.execute(same(RemovePersistentTaskAction.INSTANCE), eq(new RemovePersistentTaskAction.Request("task-B")), any()); .execute(
same(RemovePersistentTaskAction.INSTANCE),
eq(new RemovePersistentTaskAction.Request(TEST_REQUEST_TIMEOUT, "task-B")),
any()
);
doAnswer(withException(new IllegalStateException("real issue while removing task"))).when(client) doAnswer(withException(new IllegalStateException("real issue while removing task"))).when(client)
.execute(same(RemovePersistentTaskAction.INSTANCE), eq(new RemovePersistentTaskAction.Request("task-C")), any()); .execute(
same(RemovePersistentTaskAction.INSTANCE),
eq(new RemovePersistentTaskAction.Request(TEST_REQUEST_TIMEOUT, "task-C")),
any()
);
PersistentTasksService persistentTasksService = new PersistentTasksService(mock(ClusterService.class), threadPool, client); PersistentTasksService persistentTasksService = new PersistentTasksService(mock(ClusterService.class), threadPool, client);
Set<String> transformTasks = Set.of("task-A", "task-B", "task-C"); Set<String> transformTasks = Set.of("task-A", "task-B", "task-C");

View file

@ -80,6 +80,7 @@ import static org.hamcrest.Matchers.sameInstance;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -352,7 +353,7 @@ public class TransformTaskTests extends ESTestCase {
eq(42L), eq(42L),
isNull(), isNull(),
eq("Node is shutting down."), eq("Node is shutting down."),
isNull(), isNotNull(),
any() any()
); );
} }