Combine node name and task id into single string task id
This commit changes the URL for task operations from `/_tasks/{nodeId}/{taskId}` to `/_tasks/{taskId}`, where `{taskId}` has a form of nodeid:id
This commit is contained in:
parent
7140d184ab
commit
d6af669776
|
@ -36,14 +36,6 @@ public class CancelTasksRequest extends BaseTasksRequest<CancelTasksRequest> {
|
||||||
|
|
||||||
private String reason = DEFAULT_REASON;
|
private String reason = DEFAULT_REASON;
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel tasks on the specified nodes. If none are passed, all cancellable tasks on
|
|
||||||
* all nodes will be cancelled.
|
|
||||||
*/
|
|
||||||
public CancelTasksRequest(String... nodesIds) {
|
|
||||||
super(nodesIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
|
@ -54,7 +46,6 @@ public class CancelTasksRequest extends BaseTasksRequest<CancelTasksRequest> {
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeString(reason);
|
out.writeString(reason);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.action.FailedNodeException;
|
||||||
import org.elasticsearch.action.TaskOperationFailure;
|
import org.elasticsearch.action.TaskOperationFailure;
|
||||||
import org.elasticsearch.action.admin.cluster.node.tasks.list.TaskInfo;
|
import org.elasticsearch.action.admin.cluster.node.tasks.list.TaskInfo;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.tasks.BaseTasksRequest;
|
|
||||||
import org.elasticsearch.action.support.tasks.TransportTasksAction;
|
import org.elasticsearch.action.support.tasks.TransportTasksAction;
|
||||||
import org.elasticsearch.cluster.ClusterName;
|
import org.elasticsearch.cluster.ClusterName;
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
import org.elasticsearch.cluster.ClusterService;
|
||||||
|
@ -36,6 +35,7 @@ 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.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.tasks.CancellableTask;
|
import org.elasticsearch.tasks.CancellableTask;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.EmptyTransportResponseHandler;
|
import org.elasticsearch.transport.EmptyTransportResponseHandler;
|
||||||
import org.elasticsearch.transport.TransportChannel;
|
import org.elasticsearch.transport.TransportChannel;
|
||||||
|
@ -84,9 +84,9 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processTasks(CancelTasksRequest request, Consumer<CancellableTask> operation) {
|
protected void processTasks(CancelTasksRequest request, Consumer<CancellableTask> operation) {
|
||||||
if (request.taskId() != BaseTasksRequest.ALL_TASKS) {
|
if (request.taskId().isSet() == false) {
|
||||||
// we are only checking one task, we can optimize it
|
// we are only checking one task, we can optimize it
|
||||||
CancellableTask task = taskManager.getCancellableTask(request.taskId());
|
CancellableTask task = taskManager.getCancellableTask(request.taskId().getId());
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
if (request.match(task)) {
|
if (request.match(task)) {
|
||||||
operation.accept(task);
|
operation.accept(task);
|
||||||
|
@ -94,7 +94,7 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
throw new IllegalArgumentException("task [" + request.taskId() + "] doesn't support this operation");
|
throw new IllegalArgumentException("task [" + request.taskId() + "] doesn't support this operation");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (taskManager.getTask(request.taskId()) != null) {
|
if (taskManager.getTask(request.taskId().getId()) != null) {
|
||||||
// The task exists, but doesn't support cancellation
|
// The task exists, but doesn't support cancellation
|
||||||
throw new IllegalArgumentException("task [" + request.taskId() + "] doesn't support cancellation");
|
throw new IllegalArgumentException("task [" + request.taskId() + "] doesn't support cancellation");
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,11 +135,14 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBanOnNodes(String reason, CancellableTask task, Set<String> nodes, BanLock banLock) {
|
private void setBanOnNodes(String reason, CancellableTask task, Set<String> nodes, BanLock banLock) {
|
||||||
sendSetBanRequest(nodes, new BanParentTaskRequest(clusterService.localNode().getId(), task.getId(), reason), banLock);
|
sendSetBanRequest(nodes,
|
||||||
|
BanParentTaskRequest.createSetBanParentTaskRequest(new TaskId(clusterService.localNode().getId(), task.getId()), reason),
|
||||||
|
banLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeBanOnNodes(CancellableTask task, Set<String> nodes) {
|
private void removeBanOnNodes(CancellableTask task, Set<String> nodes) {
|
||||||
sendRemoveBanRequest(nodes, new BanParentTaskRequest(clusterService.localNode().getId(), task.getId()));
|
sendRemoveBanRequest(nodes,
|
||||||
|
BanParentTaskRequest.createRemoveBanParentTaskRequest(new TaskId(clusterService.localNode().getId(), task.getId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSetBanRequest(Set<String> nodes, BanParentTaskRequest request, BanLock banLock) {
|
private void sendSetBanRequest(Set<String> nodes, BanParentTaskRequest request, BanLock banLock) {
|
||||||
|
@ -148,8 +151,8 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
DiscoveryNode discoveryNode = clusterState.getNodes().get(node);
|
DiscoveryNode discoveryNode = clusterState.getNodes().get(node);
|
||||||
if (discoveryNode != null) {
|
if (discoveryNode != null) {
|
||||||
// Check if node still in the cluster
|
// Check if node still in the cluster
|
||||||
logger.debug("Sending ban for tasks with the parent [{}:{}] to the node [{}], ban [{}]", request.parentNodeId, request
|
logger.debug("Sending ban for tasks with the parent [{}] to the node [{}], ban [{}]", request.parentTaskId, node,
|
||||||
.parentTaskId, node, request.ban);
|
request.ban);
|
||||||
transportService.sendRequest(discoveryNode, BAN_PARENT_ACTION_NAME, request,
|
transportService.sendRequest(discoveryNode, BAN_PARENT_ACTION_NAME, request,
|
||||||
new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
|
new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -164,8 +167,8 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
banLock.onBanSet();
|
banLock.onBanSet();
|
||||||
logger.debug("Cannot send ban for tasks with the parent [{}:{}] to the node [{}] - the node no longer in the cluster",
|
logger.debug("Cannot send ban for tasks with the parent [{}] to the node [{}] - the node no longer in the cluster",
|
||||||
request.parentNodeId, request.parentTaskId, node);
|
request.parentTaskId, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,13 +179,12 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
DiscoveryNode discoveryNode = clusterState.getNodes().get(node);
|
DiscoveryNode discoveryNode = clusterState.getNodes().get(node);
|
||||||
if (discoveryNode != null) {
|
if (discoveryNode != null) {
|
||||||
// Check if node still in the cluster
|
// Check if node still in the cluster
|
||||||
logger.debug("Sending remove ban for tasks with the parent [{}:{}] to the node [{}]", request.parentNodeId,
|
logger.debug("Sending remove ban for tasks with the parent [{}] to the node [{}]", request.parentTaskId, node);
|
||||||
request.parentTaskId, node);
|
|
||||||
transportService.sendRequest(discoveryNode, BAN_PARENT_ACTION_NAME, request, EmptyTransportResponseHandler
|
transportService.sendRequest(discoveryNode, BAN_PARENT_ACTION_NAME, request, EmptyTransportResponseHandler
|
||||||
.INSTANCE_SAME);
|
.INSTANCE_SAME);
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Cannot send remove ban request for tasks with the parent [{}:{}] to the node [{}] - the node no longer in " +
|
logger.debug("Cannot send remove ban request for tasks with the parent [{}] to the node [{}] - the node no longer in " +
|
||||||
"the cluster", request.parentNodeId, request.parentTaskId, node);
|
"the cluster", request.parentTaskId, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,23 +220,27 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
|
|
||||||
private static class BanParentTaskRequest extends TransportRequest {
|
private static class BanParentTaskRequest extends TransportRequest {
|
||||||
|
|
||||||
private String parentNodeId;
|
private TaskId parentTaskId;
|
||||||
|
|
||||||
private long parentTaskId;
|
|
||||||
|
|
||||||
private boolean ban;
|
private boolean ban;
|
||||||
|
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|
||||||
BanParentTaskRequest(String parentNodeId, long parentTaskId, String reason) {
|
static BanParentTaskRequest createSetBanParentTaskRequest(TaskId parentTaskId, String reason) {
|
||||||
this.parentNodeId = parentNodeId;
|
return new BanParentTaskRequest(parentTaskId, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BanParentTaskRequest createRemoveBanParentTaskRequest(TaskId parentTaskId) {
|
||||||
|
return new BanParentTaskRequest(parentTaskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BanParentTaskRequest(TaskId parentTaskId, String reason) {
|
||||||
this.parentTaskId = parentTaskId;
|
this.parentTaskId = parentTaskId;
|
||||||
this.ban = true;
|
this.ban = true;
|
||||||
this.reason = reason;
|
this.reason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
BanParentTaskRequest(String parentNodeId, long parentTaskId) {
|
private BanParentTaskRequest(TaskId parentTaskId) {
|
||||||
this.parentNodeId = parentNodeId;
|
|
||||||
this.parentTaskId = parentTaskId;
|
this.parentTaskId = parentTaskId;
|
||||||
this.ban = false;
|
this.ban = false;
|
||||||
}
|
}
|
||||||
|
@ -245,8 +251,7 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
parentNodeId = in.readString();
|
parentTaskId = new TaskId(in);
|
||||||
parentTaskId = in.readLong();
|
|
||||||
ban = in.readBoolean();
|
ban = in.readBoolean();
|
||||||
if (ban) {
|
if (ban) {
|
||||||
reason = in.readString();
|
reason = in.readString();
|
||||||
|
@ -256,8 +261,7 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeString(parentNodeId);
|
parentTaskId.writeTo(out);
|
||||||
out.writeLong(parentTaskId);
|
|
||||||
out.writeBoolean(ban);
|
out.writeBoolean(ban);
|
||||||
if (ban) {
|
if (ban) {
|
||||||
out.writeString(reason);
|
out.writeString(reason);
|
||||||
|
@ -269,13 +273,13 @@ public class TransportCancelTasksAction extends TransportTasksAction<Cancellable
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(final BanParentTaskRequest request, final TransportChannel channel) throws Exception {
|
public void messageReceived(final BanParentTaskRequest request, final TransportChannel channel) throws Exception {
|
||||||
if (request.ban) {
|
if (request.ban) {
|
||||||
logger.debug("Received ban for the parent [{}:{}] on the node [{}], reason: [{}]", request.parentNodeId, request
|
logger.debug("Received ban for the parent [{}] on the node [{}], reason: [{}]", request.parentTaskId,
|
||||||
.parentTaskId, clusterService.localNode().getId(), request.reason);
|
clusterService.localNode().getId(), request.reason);
|
||||||
taskManager.setBan(request.parentNodeId, request.parentTaskId, request.reason);
|
taskManager.setBan(request.parentTaskId, request.reason);
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Removing ban for the parent [{}:{}] on the node [{}]", request.parentNodeId, request.parentTaskId,
|
logger.debug("Removing ban for the parent [{}] on the node [{}]", request.parentTaskId,
|
||||||
clusterService.localNode().getId());
|
clusterService.localNode().getId());
|
||||||
taskManager.removeBan(request.parentNodeId, request.parentTaskId);
|
taskManager.removeBan(request.parentTaskId);
|
||||||
}
|
}
|
||||||
channel.sendResponse(TransportResponse.Empty.INSTANCE);
|
channel.sendResponse(TransportResponse.Empty.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,14 +32,6 @@ public class ListTasksRequest extends BaseTasksRequest<ListTasksRequest> {
|
||||||
|
|
||||||
private boolean detailed = false;
|
private boolean detailed = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get information from nodes based on the nodes ids specified. If none are passed, information
|
|
||||||
* for all nodes will be returned.
|
|
||||||
*/
|
|
||||||
public ListTasksRequest(String... nodesIds) {
|
|
||||||
super(nodesIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should the detailed task information be returned.
|
* Should the detailed task information be returned.
|
||||||
*/
|
*/
|
||||||
|
@ -48,7 +40,7 @@ public class ListTasksRequest extends BaseTasksRequest<ListTasksRequest> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should the node settings be returned.
|
* Should the detailed task information be returned.
|
||||||
*/
|
*/
|
||||||
public ListTasksRequest detailed(boolean detailed) {
|
public ListTasksRequest detailed(boolean detailed) {
|
||||||
this.detailed = detailed;
|
this.detailed = detailed;
|
||||||
|
|
|
@ -138,11 +138,13 @@ public class ListTasksResponse extends BaseTasksResponse implements ToXContent {
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.startArray("tasks");
|
builder.startObject("tasks");
|
||||||
for(TaskInfo task : entry.getValue()) {
|
for(TaskInfo task : entry.getValue()) {
|
||||||
|
builder.startObject(task.getTaskId().toString(), XContentBuilder.FieldCaseConversion.NONE);
|
||||||
task.toXContent(builder, params);
|
task.toXContent(builder, params);
|
||||||
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.endArray();
|
builder.endObject();
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
|
|
||||||
private final DiscoveryNode node;
|
private final DiscoveryNode node;
|
||||||
|
|
||||||
private final long id;
|
private final TaskId taskId;
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|
||||||
|
@ -51,28 +52,21 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
|
|
||||||
private final Task.Status status;
|
private final Task.Status status;
|
||||||
|
|
||||||
private final String parentNode;
|
private final TaskId parentTaskId;
|
||||||
|
|
||||||
private final long parentId;
|
public TaskInfo(DiscoveryNode node, long id, String type, String action, String description, Task.Status status, TaskId parentTaskId) {
|
||||||
|
|
||||||
public TaskInfo(DiscoveryNode node, long id, String type, String action, String description, Task.Status status) {
|
|
||||||
this(node, id, type, action, description, status, null, -1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInfo(DiscoveryNode node, long id, String type, String action, String description, Task.Status status, String parentNode, long parentId) {
|
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.id = id;
|
this.taskId = new TaskId(node.getId(), id);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.parentNode = parentNode;
|
this.parentTaskId = parentTaskId;
|
||||||
this.parentId = parentId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskInfo(StreamInput in) throws IOException {
|
public TaskInfo(StreamInput in) throws IOException {
|
||||||
node = DiscoveryNode.readNode(in);
|
node = DiscoveryNode.readNode(in);
|
||||||
id = in.readLong();
|
taskId = new TaskId(node.getId(), in.readLong());
|
||||||
type = in.readString();
|
type = in.readString();
|
||||||
action = in.readString();
|
action = in.readString();
|
||||||
description = in.readOptionalString();
|
description = in.readOptionalString();
|
||||||
|
@ -81,8 +75,11 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
} else {
|
} else {
|
||||||
status = null;
|
status = null;
|
||||||
}
|
}
|
||||||
parentNode = in.readOptionalString();
|
parentTaskId = new TaskId(in);
|
||||||
parentId = in.readLong();
|
}
|
||||||
|
|
||||||
|
public TaskId getTaskId() {
|
||||||
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscoveryNode getNode() {
|
public DiscoveryNode getNode() {
|
||||||
|
@ -90,7 +87,7 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return taskId.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
|
@ -113,12 +110,8 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getParentNode() {
|
public TaskId getParentTaskId() {
|
||||||
return parentNode;
|
return parentTaskId;
|
||||||
}
|
|
||||||
|
|
||||||
public long getParentId() {
|
|
||||||
return parentId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -129,7 +122,7 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
node.writeTo(out);
|
node.writeTo(out);
|
||||||
out.writeLong(id);
|
out.writeLong(taskId.getId());
|
||||||
out.writeString(type);
|
out.writeString(type);
|
||||||
out.writeString(action);
|
out.writeString(action);
|
||||||
out.writeOptionalString(description);
|
out.writeOptionalString(description);
|
||||||
|
@ -139,15 +132,13 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
} else {
|
} else {
|
||||||
out.writeBoolean(false);
|
out.writeBoolean(false);
|
||||||
}
|
}
|
||||||
out.writeOptionalString(parentNode);
|
parentTaskId.writeTo(out);
|
||||||
out.writeLong(parentId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
|
||||||
builder.field("node", node.getId());
|
builder.field("node", node.getId());
|
||||||
builder.field("id", id);
|
builder.field("id", taskId.getId());
|
||||||
builder.field("type", type);
|
builder.field("type", type);
|
||||||
builder.field("action", action);
|
builder.field("action", action);
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
|
@ -156,11 +147,9 @@ public class TaskInfo implements Writeable<TaskInfo>, ToXContent {
|
||||||
if (description != null) {
|
if (description != null) {
|
||||||
builder.field("description", description);
|
builder.field("description", description);
|
||||||
}
|
}
|
||||||
if (parentNode != null) {
|
if (parentTaskId.isSet() == false) {
|
||||||
builder.field("parent_node", parentNode);
|
builder.field("parent_task_id", parentTaskId.toString());
|
||||||
builder.field("parent_id", parentId);
|
|
||||||
}
|
}
|
||||||
builder.endObject();
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.ActionRequest;
|
||||||
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.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -31,40 +32,35 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public abstract class ChildTaskActionRequest<Request extends ActionRequest<Request>> extends ActionRequest<Request> {
|
public abstract class ChildTaskActionRequest<Request extends ActionRequest<Request>> extends ActionRequest<Request> {
|
||||||
|
|
||||||
private String parentTaskNode;
|
private TaskId parentTaskId = TaskId.EMPTY_TASK_ID;
|
||||||
|
|
||||||
private long parentTaskId;
|
|
||||||
|
|
||||||
protected ChildTaskActionRequest() {
|
protected ChildTaskActionRequest() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParentTask(String parentTaskNode, long parentTaskId) {
|
public void setParentTask(String parentTaskNode, long parentTaskId) {
|
||||||
this.parentTaskNode = parentTaskNode;
|
this.parentTaskId = new TaskId(parentTaskNode, parentTaskId);
|
||||||
this.parentTaskId = parentTaskId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
parentTaskNode = in.readOptionalString();
|
parentTaskId = new TaskId(in);
|
||||||
parentTaskId = in.readLong();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeOptionalString(parentTaskNode);
|
parentTaskId.writeTo(out);
|
||||||
out.writeLong(parentTaskId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Task createTask(long id, String type, String action) {
|
public final Task createTask(long id, String type, String action) {
|
||||||
return createTask(id, type, action, parentTaskNode, parentTaskId);
|
return createTask(id, type, action, parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task createTask(long id, String type, String action, String parentTaskNode, long parentTaskId) {
|
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
|
||||||
return new Task(id, type, action, getDescription(), parentTaskNode, parentTaskId);
|
return new Task(id, type, action, getDescription(), parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.action.support;
|
||||||
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.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
import org.elasticsearch.transport.TransportRequest;
|
import org.elasticsearch.transport.TransportRequest;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -31,38 +32,33 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public class ChildTaskRequest extends TransportRequest {
|
public class ChildTaskRequest extends TransportRequest {
|
||||||
|
|
||||||
private String parentTaskNode;
|
private TaskId parentTaskId = TaskId.EMPTY_TASK_ID;
|
||||||
|
|
||||||
private long parentTaskId;
|
|
||||||
|
|
||||||
protected ChildTaskRequest() {
|
protected ChildTaskRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParentTask(String parentTaskNode, long parentTaskId) {
|
public void setParentTask(String parentTaskNode, long parentTaskId) {
|
||||||
this.parentTaskNode = parentTaskNode;
|
this.parentTaskId = new TaskId(parentTaskNode, parentTaskId);
|
||||||
this.parentTaskId = parentTaskId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
parentTaskNode = in.readOptionalString();
|
parentTaskId = new TaskId(in);
|
||||||
parentTaskId = in.readLong();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
out.writeOptionalString(parentTaskNode);
|
parentTaskId.writeTo(out);
|
||||||
out.writeLong(parentTaskId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Task createTask(long id, String type, String action) {
|
public final Task createTask(long id, String type, String action) {
|
||||||
return createTask(id, type, action, parentTaskNode, parentTaskId);
|
return createTask(id, type, action, parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task createTask(long id, String type, String action, String parentTaskNode, long parentTaskId) {
|
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
|
||||||
return new Task(id, type, action, getDescription(), parentTaskNode, parentTaskId);
|
return new Task(id, type, action, getDescription(), parentTaskId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -186,8 +187,8 @@ public abstract class ReplicationRequest<Request extends ReplicationRequest<Requ
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task createTask(long id, String type, String action, String parentTaskNode, long parentTaskId) {
|
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
|
||||||
return new ReplicationTask(id, type, action, getDescription(), parentTaskNode, parentTaskId);
|
return new ReplicationTask(id, type, action, getDescription(), parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.support.replication;
|
package org.elasticsearch.action.support.replication;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Provider;
|
|
||||||
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.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ import static java.util.Objects.requireNonNull;
|
||||||
public class ReplicationTask extends Task {
|
public class ReplicationTask extends Task {
|
||||||
private volatile String phase = "starting";
|
private volatile String phase = "starting";
|
||||||
|
|
||||||
public ReplicationTask(long id, String type, String action, String description, String parentNode, long parentId) {
|
public ReplicationTask(long id, String type, String action, String description, TaskId parentTaskId) {
|
||||||
super(id, type, action, description, parentNode, parentId);
|
super(id, type, action, description, parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,9 +27,12 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.regex.Regex;
|
import org.elasticsearch.common.regex.Regex;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base class for task requests
|
* A base class for task requests
|
||||||
*/
|
*/
|
||||||
|
@ -47,26 +50,21 @@ public class BaseTasksRequest<Request extends BaseTasksRequest<Request>> extends
|
||||||
|
|
||||||
private String[] actions = ALL_ACTIONS;
|
private String[] actions = ALL_ACTIONS;
|
||||||
|
|
||||||
private String parentNode;
|
private TaskId parentTaskId = TaskId.EMPTY_TASK_ID;
|
||||||
|
|
||||||
private long parentTaskId = ALL_TASKS;
|
private TaskId taskId = TaskId.EMPTY_TASK_ID;
|
||||||
|
|
||||||
private long taskId = ALL_TASKS;
|
|
||||||
|
|
||||||
public BaseTasksRequest() {
|
public BaseTasksRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionRequestValidationException validate() {
|
public ActionRequestValidationException validate() {
|
||||||
return null;
|
ActionRequestValidationException validationException = null;
|
||||||
}
|
if (taskId.isSet() == false && nodesIds.length > 0) {
|
||||||
|
validationException = addValidationError("task id cannot be used together with node ids",
|
||||||
/**
|
validationException);
|
||||||
* Get information about tasks from nodes based on the nodes ids specified.
|
}
|
||||||
* If none are passed, information for all nodes will be returned.
|
return validationException;
|
||||||
*/
|
|
||||||
public BaseTasksRequest(String... nodesIds) {
|
|
||||||
this.nodesIds = nodesIds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,39 +98,26 @@ public class BaseTasksRequest<Request extends BaseTasksRequest<Request>> extends
|
||||||
*
|
*
|
||||||
* By default tasks with any ids are returned.
|
* By default tasks with any ids are returned.
|
||||||
*/
|
*/
|
||||||
public long taskId() {
|
public TaskId taskId() {
|
||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final Request taskId(long taskId) {
|
public final Request taskId(TaskId taskId) {
|
||||||
this.taskId = taskId;
|
this.taskId = taskId;
|
||||||
return (Request) this;
|
return (Request) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the parent node id that tasks should be filtered by
|
|
||||||
*/
|
|
||||||
public String parentNode() {
|
|
||||||
return parentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Request parentNode(String parentNode) {
|
|
||||||
this.parentNode = parentNode;
|
|
||||||
return (Request) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the parent task id that tasks should be filtered by
|
* Returns the parent task id that tasks should be filtered by
|
||||||
*/
|
*/
|
||||||
public long parentTaskId() {
|
public TaskId parentTaskId() {
|
||||||
return parentTaskId;
|
return parentTaskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Request parentTaskId(long parentTaskId) {
|
public Request parentTaskId(TaskId parentTaskId) {
|
||||||
this.parentTaskId = parentTaskId;
|
this.parentTaskId = parentTaskId;
|
||||||
return (Request) this;
|
return (Request) this;
|
||||||
}
|
}
|
||||||
|
@ -157,11 +142,10 @@ public class BaseTasksRequest<Request extends BaseTasksRequest<Request>> extends
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
|
taskId = new TaskId(in);
|
||||||
|
parentTaskId = new TaskId(in);
|
||||||
nodesIds = in.readStringArray();
|
nodesIds = in.readStringArray();
|
||||||
taskId = in.readLong();
|
|
||||||
actions = in.readStringArray();
|
actions = in.readStringArray();
|
||||||
parentNode = in.readOptionalString();
|
|
||||||
parentTaskId = in.readLong();
|
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
timeout = TimeValue.readTimeValue(in);
|
timeout = TimeValue.readTimeValue(in);
|
||||||
}
|
}
|
||||||
|
@ -170,11 +154,10 @@ public class BaseTasksRequest<Request extends BaseTasksRequest<Request>> extends
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
|
taskId.writeTo(out);
|
||||||
|
parentTaskId.writeTo(out);
|
||||||
out.writeStringArrayNullable(nodesIds);
|
out.writeStringArrayNullable(nodesIds);
|
||||||
out.writeLong(taskId);
|
|
||||||
out.writeStringArrayNullable(actions);
|
out.writeStringArrayNullable(actions);
|
||||||
out.writeOptionalString(parentNode);
|
|
||||||
out.writeLong(parentTaskId);
|
|
||||||
out.writeOptionalStreamable(timeout);
|
out.writeOptionalStreamable(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,18 +165,13 @@ public class BaseTasksRequest<Request extends BaseTasksRequest<Request>> extends
|
||||||
if (actions() != null && actions().length > 0 && Regex.simpleMatch(actions(), task.getAction()) == false) {
|
if (actions() != null && actions().length > 0 && Regex.simpleMatch(actions(), task.getAction()) == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (taskId() != ALL_TASKS) {
|
if (taskId().isSet() == false) {
|
||||||
if(taskId() != task.getId()) {
|
if(taskId().getId() != task.getId()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parentNode() != null) {
|
if (parentTaskId.isSet() == false) {
|
||||||
if (parentNode().equals(task.getParentNode()) == false) {
|
if (parentTaskId.equals(task.getParentTaskId()) == false) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parentTaskId() != ALL_TASKS) {
|
|
||||||
if (parentTaskId() != task.getParentId()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,13 +124,17 @@ public abstract class TransportTasksAction<
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String[] resolveNodes(TasksRequest request, ClusterState clusterState) {
|
protected String[] resolveNodes(TasksRequest request, ClusterState clusterState) {
|
||||||
return clusterState.nodes().resolveNodesIds(request.nodesIds());
|
if (request.taskId().isSet()) {
|
||||||
|
return clusterState.nodes().resolveNodesIds(request.nodesIds());
|
||||||
|
} else {
|
||||||
|
return new String[]{request.taskId().getNodeId()};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processTasks(TasksRequest request, Consumer<OperationTask> operation) {
|
protected void processTasks(TasksRequest request, Consumer<OperationTask> operation) {
|
||||||
if (request.taskId() != BaseTasksRequest.ALL_TASKS) {
|
if (request.taskId().isSet() == false) {
|
||||||
// we are only checking one task, we can optimize it
|
// we are only checking one task, we can optimize it
|
||||||
Task task = taskManager.getTask(request.taskId());
|
Task task = taskManager.getTask(request.taskId().getId());
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
if (request.match(task)) {
|
if (request.match(task)) {
|
||||||
operation.accept((OperationTask) task);
|
operation.accept((OperationTask) task);
|
||||||
|
@ -143,13 +147,14 @@ public abstract class TransportTasksAction<
|
||||||
} else {
|
} else {
|
||||||
for (Task task : taskManager.getTasks().values()) {
|
for (Task task : taskManager.getTasks().values()) {
|
||||||
if (request.match(task)) {
|
if (request.match(task)) {
|
||||||
operation.accept((OperationTask)task);
|
operation.accept((OperationTask) task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract TasksResponse newResponse(TasksRequest request, List<TaskResponse> tasks, List<TaskOperationFailure> taskOperationFailures, List<FailedNodeException> failedNodeExceptions);
|
protected abstract TasksResponse newResponse(TasksRequest request, List<TaskResponse> tasks, List<TaskOperationFailure>
|
||||||
|
taskOperationFailures, List<FailedNodeException> failedNodeExceptions);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected TasksResponse newResponse(TasksRequest request, AtomicReferenceArray responses) {
|
protected TasksResponse newResponse(TasksRequest request, AtomicReferenceArray responses) {
|
||||||
|
@ -232,34 +237,36 @@ public abstract class TransportTasksAction<
|
||||||
onFailure(idx, nodeId, new NoSuchNodeException(nodeId));
|
onFailure(idx, nodeId, new NoSuchNodeException(nodeId));
|
||||||
} else if (!clusterService.localNode().shouldConnectTo(node) && !clusterService.localNode().equals(node)) {
|
} else if (!clusterService.localNode().shouldConnectTo(node) && !clusterService.localNode().equals(node)) {
|
||||||
// the check "!clusterService.localNode().equals(node)" is to maintain backward comp. where before
|
// the check "!clusterService.localNode().equals(node)" is to maintain backward comp. where before
|
||||||
// we allowed to connect from "local" client node to itself, certain tests rely on it, if we remove it, we need to fix
|
// we allowed to connect from "local" client node to itself, certain tests rely on it, if we remove it, we
|
||||||
|
// need to fix
|
||||||
// those (and they randomize the client node usage, so tricky to find when)
|
// those (and they randomize the client node usage, so tricky to find when)
|
||||||
onFailure(idx, nodeId, new NodeShouldNotConnectException(clusterService.localNode(), node));
|
onFailure(idx, nodeId, new NodeShouldNotConnectException(clusterService.localNode(), node));
|
||||||
} else {
|
} else {
|
||||||
NodeTaskRequest nodeRequest = new NodeTaskRequest(request);
|
NodeTaskRequest nodeRequest = new NodeTaskRequest(request);
|
||||||
nodeRequest.setParentTask(clusterService.localNode().id(), task.getId());
|
nodeRequest.setParentTask(clusterService.localNode().id(), task.getId());
|
||||||
taskManager.registerChildTask(task, node.getId());
|
taskManager.registerChildTask(task, node.getId());
|
||||||
transportService.sendRequest(node, transportNodeAction, nodeRequest, builder.build(), new BaseTransportResponseHandler<NodeTasksResponse>() {
|
transportService.sendRequest(node, transportNodeAction, nodeRequest, builder.build(),
|
||||||
@Override
|
new BaseTransportResponseHandler<NodeTasksResponse>() {
|
||||||
public NodeTasksResponse newInstance() {
|
@Override
|
||||||
return new NodeTasksResponse();
|
public NodeTasksResponse newInstance() {
|
||||||
}
|
return new NodeTasksResponse();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResponse(NodeTasksResponse response) {
|
public void handleResponse(NodeTasksResponse response) {
|
||||||
onOperation(idx, response);
|
onOperation(idx, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleException(TransportException exp) {
|
public void handleException(TransportException exp) {
|
||||||
onFailure(idx, node.id(), exp);
|
onFailure(idx, node.id(), exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String executor() {
|
public String executor() {
|
||||||
return ThreadPool.Names.SAME;
|
return ThreadPool.Names.SAME;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
onFailure(idx, nodeId, t);
|
onFailure(idx, nodeId, t);
|
||||||
|
|
|
@ -272,7 +272,7 @@ public interface ClusterAdminClient extends ElasticsearchClient {
|
||||||
*
|
*
|
||||||
* @param request The nodes tasks request
|
* @param request The nodes tasks request
|
||||||
* @return The result future
|
* @return The result future
|
||||||
* @see org.elasticsearch.client.Requests#listTasksRequest(String...)
|
* @see org.elasticsearch.client.Requests#listTasksRequest()
|
||||||
*/
|
*/
|
||||||
ActionFuture<ListTasksResponse> listTasks(ListTasksRequest request);
|
ActionFuture<ListTasksResponse> listTasks(ListTasksRequest request);
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ public interface ClusterAdminClient extends ElasticsearchClient {
|
||||||
*
|
*
|
||||||
* @param request The nodes tasks request
|
* @param request The nodes tasks request
|
||||||
* @param listener A listener to be notified with a result
|
* @param listener A listener to be notified with a result
|
||||||
* @see org.elasticsearch.client.Requests#listTasksRequest(String...)
|
* @see org.elasticsearch.client.Requests#listTasksRequest()
|
||||||
*/
|
*/
|
||||||
void listTasks(ListTasksRequest request, ActionListener<ListTasksResponse> listener);
|
void listTasks(ListTasksRequest request, ActionListener<ListTasksResponse> listener);
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ public interface ClusterAdminClient extends ElasticsearchClient {
|
||||||
*
|
*
|
||||||
* @param request The nodes tasks request
|
* @param request The nodes tasks request
|
||||||
* @return The result future
|
* @return The result future
|
||||||
* @see org.elasticsearch.client.Requests#cancelTasksRequest(String...)
|
* @see org.elasticsearch.client.Requests#cancelTasksRequest()
|
||||||
*/
|
*/
|
||||||
ActionFuture<CancelTasksResponse> cancelTasks(CancelTasksRequest request);
|
ActionFuture<CancelTasksResponse> cancelTasks(CancelTasksRequest request);
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ public interface ClusterAdminClient extends ElasticsearchClient {
|
||||||
*
|
*
|
||||||
* @param request The nodes tasks request
|
* @param request The nodes tasks request
|
||||||
* @param listener A cancelener to be notified with a result
|
* @param listener A cancelener to be notified with a result
|
||||||
* @see org.elasticsearch.client.Requests#cancelTasksRequest(String...)
|
* @see org.elasticsearch.client.Requests#cancelTasksRequest()
|
||||||
*/
|
*/
|
||||||
void cancelTasks(CancelTasksRequest request, ActionListener<CancelTasksResponse> listener);
|
void cancelTasks(CancelTasksRequest request, ActionListener<CancelTasksResponse> listener);
|
||||||
|
|
||||||
|
|
|
@ -419,23 +419,11 @@ public class Requests {
|
||||||
/**
|
/**
|
||||||
* Creates a nodes tasks request against one or more nodes. Pass <tt>null</tt> or an empty array for all nodes.
|
* Creates a nodes tasks request against one or more nodes. Pass <tt>null</tt> or an empty array for all nodes.
|
||||||
*
|
*
|
||||||
* @param nodesIds The nodes ids to get the tasks for
|
|
||||||
* @return The nodes tasks request
|
|
||||||
* @see org.elasticsearch.client.ClusterAdminClient#listTasks(ListTasksRequest)
|
|
||||||
*/
|
|
||||||
public static ListTasksRequest listTasksRequest(String... nodesIds) {
|
|
||||||
return new ListTasksRequest(nodesIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a nodes tasks request against one or more nodes. Pass <tt>null</tt> or an empty array for all nodes.
|
|
||||||
*
|
|
||||||
* @param nodesIds The nodes ids to cancel the tasks on
|
|
||||||
* @return The nodes tasks request
|
* @return The nodes tasks request
|
||||||
* @see org.elasticsearch.client.ClusterAdminClient#cancelTasks(CancelTasksRequest)
|
* @see org.elasticsearch.client.ClusterAdminClient#cancelTasks(CancelTasksRequest)
|
||||||
*/
|
*/
|
||||||
public static CancelTasksRequest cancelTasksRequest(String... nodesIds) {
|
public static CancelTasksRequest cancelTasksRequest() {
|
||||||
return new CancelTasksRequest(nodesIds);
|
return new CancelTasksRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.rest.RestChannel;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.action.support.RestToXContentListener;
|
import org.elasticsearch.rest.action.support.RestToXContentListener;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
|
||||||
|
@ -40,22 +41,20 @@ public class RestCancelTasksAction extends BaseRestHandler {
|
||||||
public RestCancelTasksAction(Settings settings, RestController controller, Client client) {
|
public RestCancelTasksAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(POST, "/_tasks/_cancel", this);
|
controller.registerHandler(POST, "/_tasks/_cancel", this);
|
||||||
controller.registerHandler(POST, "/_tasks/{nodeId}/_cancel", this);
|
controller.registerHandler(POST, "/_tasks/{taskId}/_cancel", this);
|
||||||
controller.registerHandler(POST, "/_tasks/{nodeId}/{taskId}/_cancel", this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
||||||
String[] nodesIds = Strings.splitStringByCommaToArray(request.param("nodeId"));
|
String[] nodesIds = Strings.splitStringByCommaToArray(request.param("nodeId"));
|
||||||
long taskId = request.paramAsLong("taskId", ListTasksRequest.ALL_TASKS);
|
TaskId taskId = new TaskId(request.param("taskId"));
|
||||||
String[] actions = Strings.splitStringByCommaToArray(request.param("actions"));
|
String[] actions = Strings.splitStringByCommaToArray(request.param("actions"));
|
||||||
String parentNode = request.param("parent_node");
|
TaskId parentTaskId = new TaskId(request.param("parent_task_id"));
|
||||||
long parentTaskId = request.paramAsLong("parent_task", ListTasksRequest.ALL_TASKS);
|
|
||||||
|
|
||||||
CancelTasksRequest cancelTasksRequest = new CancelTasksRequest(nodesIds);
|
CancelTasksRequest cancelTasksRequest = new CancelTasksRequest();
|
||||||
cancelTasksRequest.taskId(taskId);
|
cancelTasksRequest.taskId(taskId);
|
||||||
|
cancelTasksRequest.nodesIds(nodesIds);
|
||||||
cancelTasksRequest.actions(actions);
|
cancelTasksRequest.actions(actions);
|
||||||
cancelTasksRequest.parentNode(parentNode);
|
|
||||||
cancelTasksRequest.parentTaskId(parentTaskId);
|
cancelTasksRequest.parentTaskId(parentTaskId);
|
||||||
client.admin().cluster().cancelTasks(cancelTasksRequest, new RestToXContentListener<>(channel));
|
client.admin().cluster().cancelTasks(cancelTasksRequest, new RestToXContentListener<>(channel));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.rest.RestChannel;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.action.support.RestToXContentListener;
|
import org.elasticsearch.rest.action.support.RestToXContentListener;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||||
|
|
||||||
|
@ -39,24 +40,22 @@ public class RestListTasksAction extends BaseRestHandler {
|
||||||
public RestListTasksAction(Settings settings, RestController controller, Client client) {
|
public RestListTasksAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(GET, "/_tasks", this);
|
controller.registerHandler(GET, "/_tasks", this);
|
||||||
controller.registerHandler(GET, "/_tasks/{nodeId}", this);
|
controller.registerHandler(GET, "/_tasks/{taskId}", this);
|
||||||
controller.registerHandler(GET, "/_tasks/{nodeId}/{taskId}", this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
|
||||||
boolean detailed = request.paramAsBoolean("detailed", false);
|
boolean detailed = request.paramAsBoolean("detailed", false);
|
||||||
String[] nodesIds = Strings.splitStringByCommaToArray(request.param("nodeId"));
|
String[] nodesIds = Strings.splitStringByCommaToArray(request.param("node_id"));
|
||||||
long taskId = request.paramAsLong("taskId", ListTasksRequest.ALL_TASKS);
|
TaskId taskId = new TaskId(request.param("taskId"));
|
||||||
String[] actions = Strings.splitStringByCommaToArray(request.param("actions"));
|
String[] actions = Strings.splitStringByCommaToArray(request.param("actions"));
|
||||||
String parentNode = request.param("parent_node");
|
TaskId parentTaskId = new TaskId(request.param("parent_task_id"));
|
||||||
long parentTaskId = request.paramAsLong("parent_task", ListTasksRequest.ALL_TASKS);
|
|
||||||
|
|
||||||
ListTasksRequest listTasksRequest = new ListTasksRequest(nodesIds);
|
ListTasksRequest listTasksRequest = new ListTasksRequest();
|
||||||
listTasksRequest.taskId(taskId);
|
listTasksRequest.taskId(taskId);
|
||||||
|
listTasksRequest.nodesIds(nodesIds);
|
||||||
listTasksRequest.detailed(detailed);
|
listTasksRequest.detailed(detailed);
|
||||||
listTasksRequest.actions(actions);
|
listTasksRequest.actions(actions);
|
||||||
listTasksRequest.parentNode(parentNode);
|
|
||||||
listTasksRequest.parentTaskId(parentTaskId);
|
listTasksRequest.parentTaskId(parentTaskId);
|
||||||
client.admin().cluster().listTasks(listTasksRequest, new RestToXContentListener<>(channel));
|
client.admin().cluster().listTasks(listTasksRequest, new RestToXContentListener<>(channel));
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ public class CancellableTask extends Task {
|
||||||
super(id, type, action, description);
|
super(id, type, action, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CancellableTask(long id, String type, String action, String description, String parentNode, long parentId) {
|
public CancellableTask(long id, String type, String action, String description, TaskId parentTaskId) {
|
||||||
super(id, type, action, description, parentNode, parentId);
|
super(id, type, action, description, parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,8 +30,6 @@ import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
*/
|
*/
|
||||||
public class Task {
|
public class Task {
|
||||||
|
|
||||||
public static final long NO_PARENT_ID = 0;
|
|
||||||
|
|
||||||
private final long id;
|
private final long id;
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
@ -40,22 +38,18 @@ public class Task {
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
private final String parentNode;
|
private final TaskId parentTask;
|
||||||
|
|
||||||
private final long parentId;
|
|
||||||
|
|
||||||
|
|
||||||
public Task(long id, String type, String action, String description) {
|
public Task(long id, String type, String action, String description) {
|
||||||
this(id, type, action, description, null, NO_PARENT_ID);
|
this(id, type, action, description, TaskId.EMPTY_TASK_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task(long id, String type, String action, String description, String parentNode, long parentId) {
|
public Task(long id, String type, String action, String description, TaskId parentTask) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.parentNode = parentNode;
|
this.parentTask = parentTask;
|
||||||
this.parentId = parentId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,7 +69,7 @@ public class Task {
|
||||||
description = getDescription();
|
description = getDescription();
|
||||||
status = getStatus();
|
status = getStatus();
|
||||||
}
|
}
|
||||||
return new TaskInfo(node, getId(), getType(), getAction(), description, status, parentNode, parentId);
|
return new TaskInfo(node, getId(), getType(), getAction(), description, status, parentTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,18 +100,11 @@ public class Task {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the parent node of the task or null if the task doesn't have any parent tasks
|
|
||||||
*/
|
|
||||||
public String getParentNode() {
|
|
||||||
return parentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns id of the parent task or NO_PARENT_ID if the task doesn't have any parent tasks
|
* Returns id of the parent task or NO_PARENT_ID if the task doesn't have any parent tasks
|
||||||
*/
|
*/
|
||||||
public long getParentId() {
|
public TaskId getParentTaskId() {
|
||||||
return parentId;
|
return parentTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.tasks;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task id that consists of node id and id of the task on the node
|
||||||
|
*/
|
||||||
|
public final class TaskId implements Writeable<TaskId> {
|
||||||
|
|
||||||
|
public final static TaskId EMPTY_TASK_ID = new TaskId("", -1L);
|
||||||
|
|
||||||
|
private final String nodeId;
|
||||||
|
private final long id;
|
||||||
|
|
||||||
|
public TaskId(String nodeId, long id) {
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskId(String taskId) {
|
||||||
|
if (Strings.hasLength(taskId) && "unset".equals(taskId) == false) {
|
||||||
|
String[] s = Strings.split(taskId, ":");
|
||||||
|
if (s == null || s.length != 2) {
|
||||||
|
throw new IllegalArgumentException("malformed task id " + taskId);
|
||||||
|
}
|
||||||
|
this.nodeId = s[0];
|
||||||
|
try {
|
||||||
|
this.id = Long.parseLong(s[1]);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new IllegalArgumentException("malformed task id " + taskId, ex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nodeId = "";
|
||||||
|
id = -1L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskId(StreamInput in) throws IOException {
|
||||||
|
nodeId = in.readString();
|
||||||
|
id = in.readLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSet() {
|
||||||
|
return id == -1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (isSet()) {
|
||||||
|
return "unset";
|
||||||
|
} else {
|
||||||
|
return nodeId + ":" + id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
|
out.writeString(nodeId);
|
||||||
|
out.writeLong(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskId readFrom(StreamInput in) throws IOException {
|
||||||
|
return new TaskId(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
TaskId taskId = (TaskId) o;
|
||||||
|
|
||||||
|
if (id != taskId.id) return false;
|
||||||
|
return nodeId.equals(taskId.nodeId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = nodeId.hashCode();
|
||||||
|
result = 31 * result + (int) (id ^ (id >>> 32));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.tasks;
|
||||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||||
import org.elasticsearch.cluster.ClusterStateListener;
|
import org.elasticsearch.cluster.ClusterStateListener;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||||
import org.elasticsearch.common.collect.Tuple;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
||||||
|
@ -51,7 +50,7 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
|
|
||||||
private final AtomicLong taskIdGenerator = new AtomicLong();
|
private final AtomicLong taskIdGenerator = new AtomicLong();
|
||||||
|
|
||||||
private final Map<Tuple<String, Long>, String> banedParents = new ConcurrentHashMap<>();
|
private final Map<TaskId, String> banedParents = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public TaskManager(Settings settings) {
|
public TaskManager(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
@ -77,8 +76,8 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
CancellableTaskHolder oldHolder = cancellableTasks.put(task.getId(), holder);
|
CancellableTaskHolder oldHolder = cancellableTasks.put(task.getId(), holder);
|
||||||
assert oldHolder == null;
|
assert oldHolder == null;
|
||||||
// Check if this task was banned before we start it
|
// Check if this task was banned before we start it
|
||||||
if (task.getParentNode() != null && banedParents.isEmpty() == false) {
|
if (task.getParentTaskId().isSet() == false && banedParents.isEmpty() == false) {
|
||||||
String reason = banedParents.get(new Tuple<>(task.getParentNode(), task.getParentId()));
|
String reason = banedParents.get(task.getParentTaskId());
|
||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
try {
|
try {
|
||||||
holder.cancel(reason);
|
holder.cancel(reason);
|
||||||
|
@ -191,22 +190,21 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
* <p>
|
* <p>
|
||||||
* This method is called when a parent task that has children is cancelled.
|
* This method is called when a parent task that has children is cancelled.
|
||||||
*/
|
*/
|
||||||
public void setBan(String parentNode, long parentId, String reason) {
|
public void setBan(TaskId parentTaskId, String reason) {
|
||||||
logger.trace("setting ban for the parent task {}:{} {}", parentNode, parentId, reason);
|
logger.trace("setting ban for the parent task {} {}", parentTaskId, reason);
|
||||||
|
|
||||||
// Set the ban first, so the newly created tasks cannot be registered
|
// Set the ban first, so the newly created tasks cannot be registered
|
||||||
Tuple<String, Long> ban = new Tuple<>(parentNode, parentId);
|
|
||||||
synchronized (banedParents) {
|
synchronized (banedParents) {
|
||||||
if (lastDiscoveryNodes.nodeExists(parentNode)) {
|
if (lastDiscoveryNodes.nodeExists(parentTaskId.getNodeId())) {
|
||||||
// Only set the ban if the node is the part of the cluster
|
// Only set the ban if the node is the part of the cluster
|
||||||
banedParents.put(ban, reason);
|
banedParents.put(parentTaskId, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now go through already running tasks and cancel them
|
// Now go through already running tasks and cancel them
|
||||||
for (Map.Entry<Long, CancellableTaskHolder> taskEntry : cancellableTasks.entrySet()) {
|
for (Map.Entry<Long, CancellableTaskHolder> taskEntry : cancellableTasks.entrySet()) {
|
||||||
CancellableTaskHolder holder = taskEntry.getValue();
|
CancellableTaskHolder holder = taskEntry.getValue();
|
||||||
if (holder.hasParent(parentNode, parentId)) {
|
if (holder.hasParent(parentTaskId)) {
|
||||||
holder.cancel(reason);
|
holder.cancel(reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,9 +215,9 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
* <p>
|
* <p>
|
||||||
* This method is called when a previously banned task finally cancelled
|
* This method is called when a previously banned task finally cancelled
|
||||||
*/
|
*/
|
||||||
public void removeBan(String parentNode, long parentId) {
|
public void removeBan(TaskId parentTaskId) {
|
||||||
logger.trace("removing ban for the parent task {}:{} {}", parentNode, parentId);
|
logger.trace("removing ban for the parent task {}", parentTaskId);
|
||||||
banedParents.remove(new Tuple<>(parentNode, parentId));
|
banedParents.remove(parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -228,14 +226,12 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
synchronized (banedParents) {
|
synchronized (banedParents) {
|
||||||
lastDiscoveryNodes = event.state().getNodes();
|
lastDiscoveryNodes = event.state().getNodes();
|
||||||
// Remove all bans that were registered by nodes that are no longer in the cluster state
|
// Remove all bans that were registered by nodes that are no longer in the cluster state
|
||||||
Iterator<Tuple<String, Long>> banIterator = banedParents.keySet().iterator();
|
Iterator<TaskId> banIterator = banedParents.keySet().iterator();
|
||||||
while (banIterator.hasNext()) {
|
while (banIterator.hasNext()) {
|
||||||
Tuple<String, Long> nodeAndTaskId = banIterator.next();
|
TaskId taskId = banIterator.next();
|
||||||
String nodeId = nodeAndTaskId.v1();
|
if (lastDiscoveryNodes.nodeExists(taskId.getNodeId()) == false) {
|
||||||
Long taskId = nodeAndTaskId.v2();
|
logger.debug("Removing ban for the parent [{}] on the node [{}], reason: the parent node is gone", taskId,
|
||||||
if (lastDiscoveryNodes.nodeExists(nodeId) == false) {
|
event.state().getNodes().localNode());
|
||||||
logger.debug("Removing ban for the parent [{}:{}] on the node [{}], reason: the parent node is gone", nodeId,
|
|
||||||
taskId, event.state().getNodes().localNode());
|
|
||||||
banIterator.remove();
|
banIterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,10 +240,10 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
for (Map.Entry<Long, CancellableTaskHolder> taskEntry : cancellableTasks.entrySet()) {
|
for (Map.Entry<Long, CancellableTaskHolder> taskEntry : cancellableTasks.entrySet()) {
|
||||||
CancellableTaskHolder holder = taskEntry.getValue();
|
CancellableTaskHolder holder = taskEntry.getValue();
|
||||||
CancellableTask task = holder.getTask();
|
CancellableTask task = holder.getTask();
|
||||||
String parent = task.getParentNode();
|
TaskId parentTaskId = task.getParentTaskId();
|
||||||
if (parent != null && lastDiscoveryNodes.nodeExists(parent) == false) {
|
if (parentTaskId.isSet() == false && lastDiscoveryNodes.nodeExists(parentTaskId.getNodeId()) == false) {
|
||||||
if (task.cancelOnParentLeaving()) {
|
if (task.cancelOnParentLeaving()) {
|
||||||
holder.cancel("Coordinating node [" + parent + "] left the cluster");
|
holder.cancel("Coordinating node [" + parentTaskId.getNodeId() + "] left the cluster");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,8 +336,8 @@ public class TaskManager extends AbstractComponent implements ClusterStateListen
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasParent(String parentNode, long parentId) {
|
public boolean hasParent(TaskId parentTaskId) {
|
||||||
return parentId == task.getParentId() && parentNode.equals(task.getParentNode());
|
return task.getParentTaskId().equals(parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CancellableTask getTask() {
|
public CancellableTask getTask() {
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.tasks.CancellableTask;
|
import org.elasticsearch.tasks.CancellableTask;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
@ -87,8 +88,8 @@ public class CancellableTasksTests extends TaskManagerTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task createTask(long id, String type, String action, String parentTaskNode, long parentTaskId) {
|
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
|
||||||
return new CancellableTask(id, type, action, getDescription(), parentTaskNode, parentTaskId);
|
return new CancellableTask(id, type, action, getDescription(), parentTaskId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,9 +236,9 @@ public class CancellableTasksTests extends TaskManagerTestCase {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cancel main task
|
// Cancel main task
|
||||||
CancelTasksRequest request = new CancelTasksRequest(testNodes[0].discoveryNode.getId());
|
CancelTasksRequest request = new CancelTasksRequest();
|
||||||
request.reason("Testing Cancellation");
|
request.reason("Testing Cancellation");
|
||||||
request.taskId(mainTask.getId());
|
request.taskId(new TaskId(testNodes[0].discoveryNode.getId(), mainTask.getId()));
|
||||||
// And send the cancellation request to a random node
|
// And send the cancellation request to a random node
|
||||||
CancelTasksResponse response = testNodes[randomIntBetween(0, testNodes.length - 1)].transportCancelTasksAction.execute(request)
|
CancelTasksResponse response = testNodes[randomIntBetween(0, testNodes.length - 1)].transportCancelTasksAction.execute(request)
|
||||||
.get();
|
.get();
|
||||||
|
@ -269,7 +270,8 @@ public class CancellableTasksTests extends TaskManagerTestCase {
|
||||||
|
|
||||||
// Make sure that tasks are no longer running
|
// Make sure that tasks are no longer running
|
||||||
ListTasksResponse listTasksResponse = testNodes[randomIntBetween(0, testNodes.length - 1)]
|
ListTasksResponse listTasksResponse = testNodes[randomIntBetween(0, testNodes.length - 1)]
|
||||||
.transportListTasksAction.execute(new ListTasksRequest(testNodes[0].discoveryNode.getId()).taskId(mainTask.getId())).get();
|
.transportListTasksAction.execute(new ListTasksRequest().taskId(
|
||||||
|
new TaskId(testNodes[0].discoveryNode.getId(), mainTask.getId()))).get();
|
||||||
assertEquals(0, listTasksResponse.getTasks().size());
|
assertEquals(0, listTasksResponse.getTasks().size());
|
||||||
|
|
||||||
// Make sure that there are no leftover bans, the ban removal is async, so we might return from the cancellation
|
// Make sure that there are no leftover bans, the ban removal is async, so we might return from the cancellation
|
||||||
|
@ -311,7 +313,7 @@ public class CancellableTasksTests extends TaskManagerTestCase {
|
||||||
|
|
||||||
// Make sure that tasks are running
|
// Make sure that tasks are running
|
||||||
ListTasksResponse listTasksResponse = testNodes[randomIntBetween(0, testNodes.length - 1)]
|
ListTasksResponse listTasksResponse = testNodes[randomIntBetween(0, testNodes.length - 1)]
|
||||||
.transportListTasksAction.execute(new ListTasksRequest().parentNode(mainNode).taskId(mainTask.getId())).get();
|
.transportListTasksAction.execute(new ListTasksRequest().parentTaskId(new TaskId(mainNode, mainTask.getId()))).get();
|
||||||
assertThat(listTasksResponse.getTasks().size(), greaterThanOrEqualTo(blockOnNodes.size()));
|
assertThat(listTasksResponse.getTasks().size(), greaterThanOrEqualTo(blockOnNodes.size()));
|
||||||
|
|
||||||
// Simulate the coordinating node leaving the cluster
|
// Simulate the coordinating node leaving the cluster
|
||||||
|
@ -328,9 +330,9 @@ public class CancellableTasksTests extends TaskManagerTestCase {
|
||||||
if (simulateBanBeforeLeaving) {
|
if (simulateBanBeforeLeaving) {
|
||||||
logger.info("--> Simulate issuing cancel request on the node that is about to leave the cluster");
|
logger.info("--> Simulate issuing cancel request on the node that is about to leave the cluster");
|
||||||
// Simulate issuing cancel request on the node that is about to leave the cluster
|
// Simulate issuing cancel request on the node that is about to leave the cluster
|
||||||
CancelTasksRequest request = new CancelTasksRequest(testNodes[0].discoveryNode.getId());
|
CancelTasksRequest request = new CancelTasksRequest();
|
||||||
request.reason("Testing Cancellation");
|
request.reason("Testing Cancellation");
|
||||||
request.taskId(mainTask.getId());
|
request.taskId(new TaskId(testNodes[0].discoveryNode.getId(), mainTask.getId()));
|
||||||
// And send the cancellation request to a random node
|
// And send the cancellation request to a random node
|
||||||
CancelTasksResponse response = testNodes[0].transportCancelTasksAction.execute(request).get();
|
CancelTasksResponse response = testNodes[0].transportCancelTasksAction.execute(request).get();
|
||||||
logger.info("--> Done simulating issuing cancel request on the node that is about to leave the cluster");
|
logger.info("--> Done simulating issuing cancel request on the node that is about to leave the cluster");
|
||||||
|
@ -354,7 +356,7 @@ public class CancellableTasksTests extends TaskManagerTestCase {
|
||||||
// Make sure that tasks are no longer running
|
// Make sure that tasks are no longer running
|
||||||
try {
|
try {
|
||||||
ListTasksResponse listTasksResponse1 = testNodes[randomIntBetween(1, testNodes.length - 1)]
|
ListTasksResponse listTasksResponse1 = testNodes[randomIntBetween(1, testNodes.length - 1)]
|
||||||
.transportListTasksAction.execute(new ListTasksRequest().parentNode(mainNode).taskId(mainTask.getId())).get();
|
.transportListTasksAction.execute(new ListTasksRequest().taskId(new TaskId(mainNode, mainTask.getId()))).get();
|
||||||
assertEquals(0, listTasksResponse1.getTasks().size());
|
assertEquals(0, listTasksResponse1.getTasks().size());
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class TasksIT extends ESIntegTestCase {
|
||||||
List<TaskInfo> tasks = findEvents(ClusterHealthAction.NAME, Tuple::v1);
|
List<TaskInfo> tasks = findEvents(ClusterHealthAction.NAME, Tuple::v1);
|
||||||
|
|
||||||
// Verify that one of these tasks is a parent of another task
|
// Verify that one of these tasks is a parent of another task
|
||||||
if (tasks.get(0).getParentNode() == null) {
|
if (tasks.get(0).getParentTaskId().isSet()) {
|
||||||
assertParentTask(Collections.singletonList(tasks.get(1)), tasks.get(0));
|
assertParentTask(Collections.singletonList(tasks.get(1)), tasks.get(0));
|
||||||
} else {
|
} else {
|
||||||
assertParentTask(Collections.singletonList(tasks.get(0)), tasks.get(1));
|
assertParentTask(Collections.singletonList(tasks.get(0)), tasks.get(1));
|
||||||
|
@ -227,7 +227,9 @@ public class TasksIT extends ESIntegTestCase {
|
||||||
} else {
|
} else {
|
||||||
// A [s][r] level task should have a corresponding [s] level task on the a different node (where primary is located)
|
// A [s][r] level task should have a corresponding [s] level task on the a different node (where primary is located)
|
||||||
sTask = findEvents(RefreshAction.NAME + "[s]",
|
sTask = findEvents(RefreshAction.NAME + "[s]",
|
||||||
event -> event.v1() && taskInfo.getParentNode().equals(event.v2().getNode().getId()) && taskInfo.getDescription().equals(event.v2().getDescription()));
|
event -> event.v1() && taskInfo.getParentTaskId().getNodeId().equals(event.v2().getNode().getId()) && taskInfo
|
||||||
|
.getDescription()
|
||||||
|
.equals(event.v2().getDescription()));
|
||||||
}
|
}
|
||||||
// There should be only one parent task
|
// There should be only one parent task
|
||||||
assertEquals(1, sTask.size());
|
assertEquals(1, sTask.size());
|
||||||
|
@ -393,9 +395,10 @@ public class TasksIT extends ESIntegTestCase {
|
||||||
*/
|
*/
|
||||||
private void assertParentTask(List<TaskInfo> tasks, TaskInfo parentTask) {
|
private void assertParentTask(List<TaskInfo> tasks, TaskInfo parentTask) {
|
||||||
for (TaskInfo task : tasks) {
|
for (TaskInfo task : tasks) {
|
||||||
assertNotNull(task.getParentNode());
|
assertFalse(task.getParentTaskId().isSet());
|
||||||
assertEquals(parentTask.getNode().getId(), task.getParentNode());
|
assertEquals(parentTask.getNode().getId(), task.getParentTaskId().getNodeId());
|
||||||
assertEquals(parentTask.getId(), task.getParentId());
|
assertTrue(Strings.hasLength(task.getParentTaskId().getNodeId()));
|
||||||
|
assertEquals(parentTask.getId(), task.getParentTaskId().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.tasks.CancellableTask;
|
import org.elasticsearch.tasks.CancellableTask;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
@ -84,8 +85,8 @@ public class TestTaskPlugin extends Plugin {
|
||||||
|
|
||||||
private volatile boolean blocked = true;
|
private volatile boolean blocked = true;
|
||||||
|
|
||||||
public TestTask(long id, String type, String action, String description, String parentNode, long parentId) {
|
public TestTask(long id, String type, String action, String description, TaskId parentTaskId) {
|
||||||
super(id, type, action, description, parentNode, parentId);
|
super(id, type, action, description, parentTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlocked() {
|
public boolean isBlocked() {
|
||||||
|
@ -172,8 +173,8 @@ public class TestTaskPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task createTask(long id, String type, String action, String parentTaskNode, long parentTaskId) {
|
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
|
||||||
return new TestTask(id, type, action, this.getDescription(), parentTaskNode, parentTaskId);
|
return new TestTask(id, type, action, this.getDescription(), parentTaskId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,11 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.tasks.Task;
|
import org.elasticsearch.tasks.Task;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
import org.elasticsearch.test.tasks.MockTaskManager;
|
import org.elasticsearch.test.tasks.MockTaskManager;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
import org.elasticsearch.transport.local.LocalTransport;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -103,9 +101,9 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task createTask(long id, String type, String action, String parentTaskNode, long parentTaskId) {
|
public Task createTask(long id, String type, String action, TaskId parentTaskId) {
|
||||||
if (enableTaskManager) {
|
if (enableTaskManager) {
|
||||||
return super.createTask(id, type, action, parentTaskNode, parentTaskId);
|
return super.createTask(id, type, action, parentTaskId);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -313,7 +311,7 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
|
||||||
}
|
}
|
||||||
Task task = actions[0].execute(request, listener);
|
Task task = actions[0].execute(request, listener);
|
||||||
logger.info("Awaiting for all actions to start");
|
logger.info("Awaiting for all actions to start");
|
||||||
actionLatch.await();
|
assertTrue(actionLatch.await(10, TimeUnit.SECONDS));
|
||||||
logger.info("Done waiting for all actions to start");
|
logger.info("Done waiting for all actions to start");
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
@ -426,14 +424,13 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
|
||||||
|
|
||||||
// Find tasks with common parent
|
// Find tasks with common parent
|
||||||
listTasksRequest = new ListTasksRequest();
|
listTasksRequest = new ListTasksRequest();
|
||||||
listTasksRequest.parentNode(parentNode);
|
listTasksRequest.parentTaskId(new TaskId(parentNode, parentTaskId));
|
||||||
listTasksRequest.parentTaskId(parentTaskId);
|
|
||||||
response = testNode.transportListTasksAction.execute(listTasksRequest).get();
|
response = testNode.transportListTasksAction.execute(listTasksRequest).get();
|
||||||
assertEquals(testNodes.length, response.getTasks().size());
|
assertEquals(testNodes.length, response.getTasks().size());
|
||||||
for (TaskInfo task : response.getTasks()) {
|
for (TaskInfo task : response.getTasks()) {
|
||||||
assertEquals("testAction[n]", task.getAction());
|
assertEquals("testAction[n]", task.getAction());
|
||||||
assertEquals(parentNode, task.getParentNode());
|
assertEquals(parentNode, task.getParentTaskId().getNodeId());
|
||||||
assertEquals(parentTaskId, task.getParentId());
|
assertEquals(parentTaskId, task.getParentTaskId().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release all tasks and wait for response
|
// Release all tasks and wait for response
|
||||||
|
@ -514,7 +511,8 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
|
||||||
String actionName = "testAction"; // only pick the main action
|
String actionName = "testAction"; // only pick the main action
|
||||||
|
|
||||||
// Try to cancel main task using action name
|
// Try to cancel main task using action name
|
||||||
CancelTasksRequest request = new CancelTasksRequest(testNodes[0].discoveryNode.getId());
|
CancelTasksRequest request = new CancelTasksRequest();
|
||||||
|
request.nodesIds(testNodes[0].discoveryNode.getId());
|
||||||
request.reason("Testing Cancellation");
|
request.reason("Testing Cancellation");
|
||||||
request.actions(actionName);
|
request.actions(actionName);
|
||||||
CancelTasksResponse response = testNodes[randomIntBetween(0, testNodes.length - 1)].transportCancelTasksAction.execute(request)
|
CancelTasksResponse response = testNodes[randomIntBetween(0, testNodes.length - 1)].transportCancelTasksAction.execute(request)
|
||||||
|
@ -527,9 +525,9 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
|
||||||
|
|
||||||
|
|
||||||
// Try to cancel main task using id
|
// Try to cancel main task using id
|
||||||
request = new CancelTasksRequest(testNodes[0].discoveryNode.getId());
|
request = new CancelTasksRequest();
|
||||||
request.reason("Testing Cancellation");
|
request.reason("Testing Cancellation");
|
||||||
request.taskId(task.getId());
|
request.taskId(new TaskId(testNodes[0].discoveryNode.getId(), task.getId()));
|
||||||
response = testNodes[randomIntBetween(0, testNodes.length - 1)].transportCancelTasksAction.execute(request).get();
|
response = testNodes[randomIntBetween(0, testNodes.length - 1)].transportCancelTasksAction.execute(request).get();
|
||||||
|
|
||||||
// Shouldn't match any tasks since testAction doesn't support cancellation
|
// Shouldn't match any tasks since testAction doesn't support cancellation
|
||||||
|
@ -601,7 +599,7 @@ public class TransportTasksActionTests extends TaskManagerTestCase {
|
||||||
@Override
|
@Override
|
||||||
protected TestTaskResponse taskOperation(TestTasksRequest request, Task task) {
|
protected TestTaskResponse taskOperation(TestTasksRequest request, Task task) {
|
||||||
logger.info("Task action on node " + node);
|
logger.info("Task action on node " + node);
|
||||||
if (failTaskOnNode == node && task.getParentNode() != null) {
|
if (failTaskOnNode == node && task.getParentTaskId().isSet() == false) {
|
||||||
logger.info("Failing on node " + node);
|
logger.info("Failing on node " + node);
|
||||||
throw new RuntimeException("Task level failure");
|
throw new RuntimeException("Task level failure");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ public class TransportReplicationActionTests extends ESTestCase {
|
||||||
* half the time.
|
* half the time.
|
||||||
*/
|
*/
|
||||||
private ReplicationTask maybeTask() {
|
private ReplicationTask maybeTask() {
|
||||||
return random().nextBoolean() ? new ReplicationTask(0, null, null, null, null, 0) : null;
|
return random().nextBoolean() ? new ReplicationTask(0, null, null, null, null) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
"methods": ["POST"],
|
"methods": ["POST"],
|
||||||
"url": {
|
"url": {
|
||||||
"path": "/_tasks",
|
"path": "/_tasks",
|
||||||
"paths": ["/_tasks/_cancel", "/_tasks/{node_id}/_cancel", "/_tasks/{node_id}/{task_id}/_cancel"],
|
"paths": ["/_tasks/_cancel", "/_tasks/{task_id}/_cancel"],
|
||||||
"parts": {
|
"parts": {
|
||||||
"node_id": {
|
|
||||||
"type": "list",
|
|
||||||
"description": "A comma-separated list of node IDs or names to limit the request; use `_local` to cancel only tasks on the node you're connecting to, leave empty to cancel tasks on all nodes"
|
|
||||||
},
|
|
||||||
"task_id": {
|
"task_id": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "Cancel the task with specified id"
|
"description": "Cancel the task with specified id"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
|
"node_id": {
|
||||||
|
"type": "list",
|
||||||
|
"description": "A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes"
|
||||||
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"description": "A comma-separated list of actions that should be cancelled. Leave empty to cancel all."
|
"description": "A comma-separated list of actions that should be cancelled. Leave empty to cancel all."
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
"methods": ["GET"],
|
"methods": ["GET"],
|
||||||
"url": {
|
"url": {
|
||||||
"path": "/_tasks",
|
"path": "/_tasks",
|
||||||
"paths": ["/_tasks", "/_tasks/{node_id}", "/_tasks/{node_id}/{task_id}"],
|
"paths": ["/_tasks", "/_tasks/{task_id}"],
|
||||||
"parts": {
|
"parts": {
|
||||||
"node_id": {
|
|
||||||
"type": "list",
|
|
||||||
"description": "A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes"
|
|
||||||
},
|
|
||||||
"task_id": {
|
"task_id": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "Return the task with specified id"
|
"description": "Return the task with specified id"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
|
"node_id": {
|
||||||
|
"type": "list",
|
||||||
|
"description": "A comma-separated list of node IDs or names to limit the returned information; use `_local` to return information from the node you're connecting to, leave empty to get information from all nodes"
|
||||||
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"description": "A comma-separated list of actions that should be returned. Leave empty to return all."
|
"description": "A comma-separated list of actions that should be returned. Leave empty to return all."
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
"tasks_cancel test":
|
"tasks_cancel test":
|
||||||
- do:
|
- do:
|
||||||
tasks.cancel:
|
tasks.cancel:
|
||||||
node_id: _local
|
actions: "unknown_action"
|
||||||
task_id: 1
|
|
||||||
|
|
||||||
- length: { nodes: 0 }
|
- length: { nodes: 0 }
|
||||||
|
|
Loading…
Reference in New Issue