From 59f53dda9fd8785bf63da9c767eb1cb3df91ab1b Mon Sep 17 00:00:00 2001 From: gesino Date: Tue, 17 Sep 2019 09:57:42 +0200 Subject: [PATCH 1/6] Fixing HLRC parsing of CancelTasks response (#45414) --- .../client/RequestConverters.java | 16 +- .../org/elasticsearch/client/TasksClient.java | 17 +- .../client/TasksRequestConverters.java | 4 +- .../client/tasks/CancelTasksRequest.java | 130 ++++++++++ .../client/tasks/CancelTasksResponse.java | 173 ++++++++++++++ .../client/tasks/ElasticsearchException.java | 222 ++++++++++++++++++ .../client/tasks/GetTaskRequest.java | 4 +- .../client/tasks/GetTaskResponse.java | 11 +- .../elasticsearch/client/tasks/NodeData.java | 169 +++++++++++++ .../client/tasks/NodesInfoData.java | 51 ++++ .../elasticsearch/client/tasks/TaskGroup.java | 93 ++++++++ .../elasticsearch/client/tasks/TaskId.java | 93 ++++++++ .../elasticsearch/client/tasks/TaskInfo.java | 198 ++++++++++++++++ .../client/tasks/TaskOperationFailure.java | 105 +++++++++ .../org/elasticsearch/client/TasksIT.java | 15 +- .../client/TasksRequestConvertersTests.java | 9 +- .../TasksClientDocumentationIT.java | 20 +- 17 files changed, 1284 insertions(+), 46 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index ceb87009b6291..093062b85f3b9 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -53,6 +53,7 @@ import org.elasticsearch.client.core.TermVectorsRequest; import org.elasticsearch.client.indices.AnalyzeRequest; import org.elasticsearch.client.security.RefreshPolicy; +import org.elasticsearch.client.tasks.TaskId; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Priority; @@ -80,7 +81,6 @@ import org.elasticsearch.script.mustache.MultiSearchTemplateRequest; import org.elasticsearch.script.mustache.SearchTemplateRequest; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; -import org.elasticsearch.tasks.TaskId; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -1042,6 +1042,20 @@ Params withActions(String[] actions) { return this; } + Params withTaskId(org.elasticsearch.tasks.TaskId taskId) { + if (taskId != null && taskId.isSet()) { + return putParam("task_id", taskId.toString()); + } + return this; + } + + Params withParentTaskId(org.elasticsearch.tasks.TaskId parentTaskId) { + if (parentTaskId != null && parentTaskId.isSet()) { + return putParam("parent_task_id", parentTaskId.toString()); + } + return this; + } + Params withTaskId(TaskId taskId) { if (taskId != null && taskId.isSet()) { return putParam("task_id", taskId.toString()); diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java index 04ccd3239335f..2c9f461b5d246 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java @@ -20,10 +20,10 @@ package org.elasticsearch.client; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; +import org.elasticsearch.client.tasks.CancelTasksRequest; +import org.elasticsearch.client.tasks.CancelTasksResponse; import org.elasticsearch.client.tasks.GetTaskRequest; import org.elasticsearch.client.tasks.GetTaskResponse; @@ -102,17 +102,7 @@ public Cancellable getAsync(GetTaskRequest request, RequestOptions options, GetTaskResponse::fromXContent, listener); } - /** - * Cancel one or more cluster tasks using the Task Management API. - * - * See - * Task Management API on elastic.co - * @param cancelTasksRequest the request - * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized - * @return the response - * @throws IOException in case there is a problem sending the request or parsing back the response - * - */ + public CancelTasksResponse cancel(CancelTasksRequest cancelTasksRequest, RequestOptions options ) throws IOException { return restHighLevelClient.performRequestAndParseEntity( cancelTasksRequest, @@ -135,6 +125,7 @@ public CancelTasksResponse cancel(CancelTasksRequest cancelTasksRequest, Request */ public Cancellable cancelAsync(CancelTasksRequest cancelTasksRequest, RequestOptions options, ActionListener listener) { + return restHighLevelClient.performRequestAsyncAndParseEntity( cancelTasksRequest, TasksRequestConverters::cancelTasks, diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java index f30efabc823e3..4a78c561db07b 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java @@ -21,9 +21,9 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; import org.elasticsearch.client.RequestConverters.EndpointBuilder; +import org.elasticsearch.client.tasks.CancelTasksRequest; import org.elasticsearch.client.tasks.GetTaskRequest; final class TasksRequestConverters { @@ -70,5 +70,5 @@ static Request getTask(GetTaskRequest getTaskRequest) { request.addParameters(params.asMap()); return request; } - + } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java new file mode 100644 index 0000000000000..8da965a6f018e --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java @@ -0,0 +1,130 @@ +/* + * 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.client.tasks; + +import org.elasticsearch.client.Validatable; +import org.elasticsearch.common.unit.TimeValue; + +import java.util.Arrays; +import java.util.Objects; + +public class CancelTasksRequest implements Validatable { + + public static final String[] EMPTY_ARRAY = new String[0]; + public static final String[] ALL_ACTIONS = EMPTY_ARRAY; + public static final String[] ALL_NODES = EMPTY_ARRAY; + private String[] nodes = ALL_NODES; + private TimeValue timeout; + private String[] actions = ALL_ACTIONS; + private TaskId parentTaskId = TaskId.EMPTY_TASK_ID; + private TaskId taskId = TaskId.EMPTY_TASK_ID; + private String reason = ""; + + public final CancelTasksRequest setNodes(String... nodes) { + this.nodes = nodes; + return this; + } + + public String[] getNodes() { + return nodes; + } + + public CancelTasksRequest setTimeout(TimeValue timeout) { + this.timeout = timeout; + return this; + } + + public final CancelTasksRequest setTimeout(String timeout) { + this.timeout = TimeValue.parseTimeValue(timeout, null, getClass().getSimpleName() + ".timeout"); + return this; + } + + public TimeValue getTimeout() { + return timeout; + } + + public CancelTasksRequest setActions(String... actions) { + this.actions = actions; + return this; + } + + public String[] getActions() { + return actions; + } + + public CancelTasksRequest setParentTaskId(TaskId parentTaskId) { + this.parentTaskId = parentTaskId; + return this; + } + + public TaskId getParentTaskId() { + return parentTaskId; + } + + public CancelTasksRequest setTaskId(TaskId taskId) { + this.taskId = taskId; + return this; + } + + public TaskId getTaskId() { + return taskId; + } + + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CancelTasksRequest)) return false; + CancelTasksRequest that = (CancelTasksRequest) o; + return Arrays.equals(getNodes(), that.getNodes()) && + Objects.equals(getTimeout(), that.getTimeout()) && + Arrays.equals(getActions(), that.getActions()) && + Objects.equals(getParentTaskId(), that.getParentTaskId()) && + Objects.equals(getTaskId(), that.getTaskId()) && + Objects.equals(getReason(), that.getReason()); + } + + @Override + public int hashCode() { + int result = Objects.hash(getTimeout(), getParentTaskId(), getTaskId(), getReason()); + result = 31 * result + Arrays.hashCode(getNodes()); + result = 31 * result + Arrays.hashCode(getActions()); + return result; + } + + @Override + public String toString() { + return "CancelTasksRequest{" + + "nodes=" + Arrays.toString(nodes) + + ", timeout=" + timeout + + ", actions=" + Arrays.toString(actions) + + ", parentTaskId=" + parentTaskId + + ", taskId=" + taskId + + ", reason='" + reason + '\'' + + '}'; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java new file mode 100644 index 0000000000000..9750367c8d6eb --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java @@ -0,0 +1,173 @@ +/* + * 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.client.tasks; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; + +public class CancelTasksResponse { + + private final NodesInfoData nodesInfoData; + private final List taskFailures = new ArrayList<>(); + private final List nodeFailures = new ArrayList<>(); + private final List tasks = new ArrayList<>(); + private final List taskGroups = new ArrayList<>(); + + public CancelTasksResponse(NodesInfoData nodesInfoData, + List taskFailures, + List nodeFailures) { + this.nodesInfoData = nodesInfoData; + if (taskFailures!= null){ + this.taskFailures.addAll(taskFailures); + } + if (nodeFailures!=null) { + this.nodeFailures.addAll(nodeFailures); + } + this.tasks.addAll(nodesInfoData + .getNodesInfoData() + .stream() + .flatMap(nodeData -> nodeData.getTasks().stream()) + .collect(toList()) + ); + + this.taskGroups.addAll(buildTaskGroups()); + } + + private List buildTaskGroups() { + Map taskGroups = new HashMap<>(); + List topLevelTasks = new ArrayList<>(); + // First populate all tasks + for (TaskInfo taskInfo : this.tasks) { + taskGroups.put(taskInfo.getTaskId(), TaskGroup.builder(taskInfo)); + } + + // Now go through all task group builders and add children to their parents + for (TaskGroup.Builder taskGroup : taskGroups.values()) { + TaskId parentTaskId = taskGroup.getTaskInfo().getParentTaskId(); + if (parentTaskId.isSet()) { + TaskGroup.Builder parentTask = taskGroups.get(parentTaskId); + if (parentTask != null) { + // we found parent in the list of tasks - add it to the parent list + parentTask.addGroup(taskGroup); + } else { + // we got zombie or the parent was filtered out - add it to the top task list + topLevelTasks.add(taskGroup); + } + } else { + // top level task - add it to the top task list + topLevelTasks.add(taskGroup); + } + } + return Collections.unmodifiableList(topLevelTasks.stream().map(TaskGroup.Builder::build).collect(Collectors.toList())); + } + + public NodesInfoData getNodesInfoData() { + return nodesInfoData; + } + + public List getTasks() { + return tasks; + } + + public Map> getPerNodeTasks() { + return getTasks() + .stream() + .collect(groupingBy(TaskInfo::getNodeId)); + } + + public List getTaskFailures() { + return taskFailures; + } + + public List getNodeFailures() { + return nodeFailures; + } + + public List getTaskGroups() { + return taskGroups; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof CancelTasksResponse)) return false; + CancelTasksResponse response = (CancelTasksResponse) o; + return getNodesInfoData().equals(response.getNodesInfoData()) && + Objects.equals(getTaskFailures(), response.getTaskFailures()) && + Objects.equals(getNodeFailures(), response.getNodeFailures()) && + Objects.equals(getTasks(), response.getTasks()) && + Objects.equals(getTaskGroups(), response.getTaskGroups()); + } + + @Override + public int hashCode() { + return Objects.hash(getNodesInfoData(), getTaskFailures(), getNodeFailures(), getTasks(), getTaskGroups()); + } + + public static CancelTasksResponse fromXContent(final XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + @Override + public String toString() { + return "CancelTasksResponse{" + + "nodesInfoData=" + nodesInfoData + + ", taskFailures=" + taskFailures + + ", nodeFailures=" + nodeFailures + + ", tasks=" + tasks + + ", taskGroups=" + taskGroups + + '}'; + } + + private static ConstructingObjectParser PARSER; + + static { + ConstructingObjectParser parser = new ConstructingObjectParser<>("cancel_tasks_response", true, + constructingObjects -> { + int i = 0; + @SuppressWarnings("unchecked") + List tasksFailures = (List) constructingObjects[i++]; + @SuppressWarnings("unchecked") + List nodeFailures = (List) constructingObjects[i++]; + NodesInfoData nodesInfoData = (NodesInfoData) constructingObjects[i]; + return new CancelTasksResponse(nodesInfoData, tasksFailures, nodeFailures); + }); + + parser.declareObjectArray(optionalConstructorArg(), (p, c) -> + TaskOperationFailure.fromXContent(p), new ParseField("task_failures")); + parser.declareObjectArray(optionalConstructorArg(), (p, c) -> + ElasticsearchException.fromXContent(p), new ParseField("node_failures")); + parser.declareObject(optionalConstructorArg(), NodesInfoData.PARSER, new ParseField("nodes")); + PARSER = parser; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java new file mode 100644 index 0000000000000..cac6d4c9826fd --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java @@ -0,0 +1,222 @@ +/* + * 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.client.tasks; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.XContentParser; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + +/** + * client side counterpart of server side + * {@link org.elasticsearch.ElasticsearchException} + */ +public class ElasticsearchException extends RuntimeException { + + private static final String TYPE = "type"; + private static final String REASON = "reason"; + private static final String CAUSED_BY = "caused_by"; + private static final ParseField SUPPRESSED = new ParseField("suppressed"); + private static final String STACK_TRACE = "stack_trace"; + private static final String HEADER = "header"; + private static final String ROOT_CAUSE = "root_cause"; + private final Map> metadata = new HashMap<>(); + private final Map> headers = new HashMap<>(); + private Object[] args; + + public ElasticsearchException(){} + + public ElasticsearchException(String msg, Throwable cause, Object... args) { + super(msg,cause); + this.args = args; + } + + /** + * Generate a {@link ElasticsearchException} from a {@link XContentParser}. This does not + * return the original exception type (ie NodeClosedException for example) but just wraps + * the type, the reason and the cause of the exception. It also recursively parses the + * tree structure of the cause, returning it as a tree structure of {@link ElasticsearchException} + * instances. + */ + public static ElasticsearchException fromXContent(XContentParser parser) throws IOException { + XContentParser.Token token = parser.nextToken(); + ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); + return innerFromXContent(parser, false); + } + + public static ElasticsearchException innerFromXContent(XContentParser parser, boolean parseRootCauses) throws IOException { + XContentParser.Token token = parser.currentToken(); + ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); + + String type = null, reason = null, stack = null; + ElasticsearchException cause = null; + Map> metadata = new HashMap<>(); + Map> headers = new HashMap<>(); + List rootCauses = new ArrayList<>(); + List suppressed = new ArrayList<>(); + + for (; token == XContentParser.Token.FIELD_NAME; token = parser.nextToken()) { + String currentFieldName = parser.currentName(); + token = parser.nextToken(); + + if (token.isValue()) { + if (TYPE.equals(currentFieldName)) { + type = parser.text(); + } else if (REASON.equals(currentFieldName)) { + reason = parser.text(); + } else if (STACK_TRACE.equals(currentFieldName)) { + stack = parser.text(); + } else if (token == XContentParser.Token.VALUE_STRING) { + metadata.put(currentFieldName, Collections.singletonList(parser.text())); + } + } else if (token == XContentParser.Token.START_OBJECT) { + if (CAUSED_BY.equals(currentFieldName)) { + cause = fromXContent(parser); + } else if (HEADER.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else { + List values = headers.getOrDefault(currentFieldName, new ArrayList<>()); + if (token == XContentParser.Token.VALUE_STRING) { + values.add(parser.text()); + } else if (token == XContentParser.Token.START_ARRAY) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + if (token == XContentParser.Token.VALUE_STRING) { + values.add(parser.text()); + } else { + parser.skipChildren(); + } + } + } else if (token == XContentParser.Token.START_OBJECT) { + parser.skipChildren(); + } + headers.put(currentFieldName, values); + } + } + } else { + // Any additional metadata object added by the metadataToXContent method is ignored + // and skipped, so that the parser does not fail on unknown fields. The parser only + // support metadata key-pairs and metadata arrays of values. + parser.skipChildren(); + } + } else if (token == XContentParser.Token.START_ARRAY) { + if (parseRootCauses && ROOT_CAUSE.equals(currentFieldName)) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + rootCauses.add(fromXContent(parser)); + } + } else if (SUPPRESSED.match(currentFieldName, parser.getDeprecationHandler())) { + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + suppressed.add(fromXContent(parser)); + } + } else { + // Parse the array and add each item to the corresponding list of metadata. + // Arrays of objects are not supported yet and just ignored and skipped. + List values = new ArrayList<>(); + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { + if (token == XContentParser.Token.VALUE_STRING) { + values.add(parser.text()); + } else { + parser.skipChildren(); + } + } + if (values.size() > 0) { + if (metadata.containsKey(currentFieldName)) { + values.addAll(metadata.get(currentFieldName)); + } + metadata.put(currentFieldName, values); + } + } + } + } + + ElasticsearchException e = new ElasticsearchException(buildMessage(type, reason, stack), cause); + for (Map.Entry> entry : metadata.entrySet()) { + e.addMetadata("es." + entry.getKey(), entry.getValue()); + } + for (Map.Entry> header : headers.entrySet()) { + e.addHeader(header.getKey(), header.getValue()); + } + + // Adds root causes as suppressed exception. This way they are not lost + // after parsing and can be retrieved using getSuppressed() method. + for (ElasticsearchException rootCause : rootCauses) { + e.addSuppressed(rootCause); + } + for (ElasticsearchException s : suppressed) { + e.addSuppressed(s); + } + return e; + } + + private void addHeader(String key, List value) { + headers.put(key,value); + + } + + private void addMetadata(String s, List value) { + metadata.put(s,value); + } + + static String buildMessage(String type, String reason, String stack) { + StringBuilder message = new StringBuilder("Elasticsearch exception ["); + message.append(TYPE).append('=').append(type).append(", "); + message.append(REASON).append('=').append(reason); + if (stack != null) { + message.append(", ").append(STACK_TRACE).append('=').append(stack); + } + message.append(']'); + return message.toString(); + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ElasticsearchException)) return false; + ElasticsearchException that = (ElasticsearchException) o; + return Objects.equals(metadata, that.metadata) && + Objects.equals(headers, that.headers) && + Objects.equals(getCause(), that.getCause()) ; + } + + @Override + public int hashCode() { + return Objects.hash(metadata, headers,getCause()); + } + + @Override + public String toString() { + return "ElasticsearchException{" + + "cause=" + getCause() + + "metadata=" + metadata + + ", headers=" + headers + + '}'; + } + + public Object[] getArgs() { + return args; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskRequest.java index 0dc3168937573..1e49e82967792 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskRequest.java @@ -101,8 +101,8 @@ public boolean equals(Object obj) { } GetTaskRequest other = (GetTaskRequest) obj; return Objects.equals(nodeId, other.nodeId) && - taskId == other.taskId && - waitForCompletion == other.waitForCompletion && + taskId == other.taskId && + waitForCompletion == other.waitForCompletion && Objects.equals(timeout, other.timeout); } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskResponse.java index 05d40f12f5b21..0bacd6ed0c514 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/GetTaskResponse.java @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package org.elasticsearch.client.tasks; import org.elasticsearch.common.ParseField; @@ -31,16 +30,16 @@ public class GetTaskResponse { private final TaskInfo taskInfo; public static final ParseField COMPLETED = new ParseField("completed"); public static final ParseField TASK = new ParseField("task"); - + public GetTaskResponse(boolean completed, TaskInfo taskInfo) { this.completed = completed; this.taskInfo = taskInfo; } - + public boolean isCompleted() { return completed; } - + public TaskInfo getTaskInfo() { return taskInfo; } @@ -50,9 +49,9 @@ public TaskInfo getTaskInfo() { static { PARSER.declareBoolean(constructorArg(), COMPLETED); PARSER.declareObject(constructorArg(), (p, c) -> TaskInfo.fromXContent(p), TASK); - } + } public static GetTaskResponse fromXContent(XContentParser parser) { return PARSER.apply(parser, null); - } + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java new file mode 100644 index 0000000000000..a0e3cef658ec0 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java @@ -0,0 +1,169 @@ +/* + * 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.client.tasks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiConsumer; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +public class NodeData { + + private String nodeId; + private String name; + private String transportAddress; + private String host; + private String ip; + private final List roles = new ArrayList<>(); + private final Map attributes = new HashMap<>(); + private final List tasks = new ArrayList<>(); + + /** + * as it is a named object + * in the JSON structure, it requires + * a name in the constructor to cope with signature of: + * {@link ObjectParser#declareNamedObjects(BiConsumer, ObjectParser.NamedObjectParser,ParseField)} + * + * @param nodeId the string identifier of a node + */ + private NodeData(String nodeId) { + this.nodeId = nodeId; + } + + private void setName(String name) { + this.name = name; + } + + public void setAttributes(Map attributes) { + if(attributes!=null){ + this.attributes.putAll(attributes); + } + } + + private void setTransportAddress(String transportAddress) { + this.transportAddress = transportAddress; + } + + private void setHost(String host) { + this.host = host; + } + + private void setIp(String ip) { + this.ip = ip; + } + + private void setRoles(List roles) { + if(roles!=null){ + this.roles.addAll(roles); + } + } + + public String getNodeId() { + return nodeId; + } + + public String getName() { + return name; + } + + public String getTransportAddress() { + return transportAddress; + } + + public String getHost() { + return host; + } + + public String getIp() { + return ip; + } + + public List getRoles() { + return roles; + } + + public Map getAttributes() { + return attributes; + } + + public List getTasks() { + return tasks; + } + + private void setTasks(List tasks) { + if(tasks!=null){ + this.tasks.addAll(tasks); + } + } + + @Override + public String toString() { + return "NodeData{" + + "nodeId='" + nodeId + '\'' + + ", name='" + name + '\'' + + ", transportAddress='" + transportAddress + '\'' + + ", host='" + host + '\'' + + ", ip='" + ip + '\'' + + ", roles=" + roles + + ", attributes=" + attributes + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof NodeData)) return false; + NodeData nodeData = (NodeData) o; + return Objects.equals(getNodeId(), nodeData.getNodeId()) && + Objects.equals(getName(), nodeData.getName()) && + Objects.equals(getTransportAddress(), nodeData.getTransportAddress()) && + Objects.equals(getHost(), nodeData.getHost()) && + Objects.equals(getIp(), nodeData.getIp()) && + Objects.equals(getRoles(), nodeData.getRoles()) && + Objects.equals(getAttributes(), nodeData.getAttributes()) && + Objects.equals(getTasks(), nodeData.getTasks()); + } + + @Override + public int hashCode() { + return Objects.hash(getNodeId(), getName(), getTransportAddress(), getHost(), getIp(), getRoles(), getAttributes(), getTasks()); + } + + public static final ObjectParser.NamedObjectParser PARSER; + + static { + ObjectParser parser = new ObjectParser<>("nodes"); + parser.declareString(NodeData::setName, new ParseField("name")); + parser.declareString(NodeData::setTransportAddress, new ParseField("transport_address")); + parser.declareString(NodeData::setHost, new ParseField("host")); + parser.declareString(NodeData::setIp, new ParseField("ip")); + parser.declareStringArray(NodeData::setRoles, new ParseField("roles")); + parser.declareField(NodeData::setAttributes, + (p, c) -> p.mapStrings(), + new ParseField("attributes"), + ObjectParser.ValueType.OBJECT); + parser.declareNamedObjects(NodeData::setTasks, TaskInfo.PARSER, new ParseField("tasks")); + PARSER = (XContentParser p, Void v, String name) -> parser.parse(p, new NodeData(name), null); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java new file mode 100644 index 0000000000000..d39e84aee919e --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java @@ -0,0 +1,51 @@ +/* + * 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.client.tasks; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ObjectParser; + +import java.util.ArrayList; +import java.util.List; + +/** + * Holder of data created out of a {@link CancelTasksResponse} + */ +public class NodesInfoData { + + private final List nodesInfoData = new ArrayList<>(); + + NodesInfoData() {} + + public List getNodesInfoData() { + return nodesInfoData; + } + + private void setNodesInfoData(List nodesInfoData) { + if(nodesInfoData!=null){ + this.nodesInfoData.addAll(nodesInfoData); + } + } + + public static final ObjectParser PARSER = new ObjectParser<>("nodes", NodesInfoData::new); + + static { + PARSER.declareNamedObjects(NodesInfoData::setNodesInfoData, NodeData.PARSER, new ParseField("nodes")); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java new file mode 100644 index 0000000000000..f13ae2160f369 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java @@ -0,0 +1,93 @@ +/* + * 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.client.tasks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Client side counterpart of server side version. + * + * {@link org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup} + */ +public class TaskGroup { + + private final TaskInfo task; + + private final List childTasks = new ArrayList<>(); + + public TaskGroup(TaskInfo task, List childTasks) { + this.task = task; + this.childTasks.addAll(childTasks); + } + + public static TaskGroup.Builder builder(TaskInfo taskInfo) { + return new TaskGroup.Builder(taskInfo); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TaskGroup)) return false; + TaskGroup taskGroup = (TaskGroup) o; + return task.equals(taskGroup.task) && + getChildTasks().equals(taskGroup.getChildTasks()); + } + + @Override + public int hashCode() { + return Objects.hash(task, getChildTasks()); + } + + public static class Builder { + private TaskInfo taskInfo; + private List childTasks; + + private Builder(TaskInfo taskInfo) { + this.taskInfo = taskInfo; + childTasks = new ArrayList<>(); + } + + public void addGroup(TaskGroup.Builder builder) { + childTasks.add(builder); + } + + public TaskInfo getTaskInfo() { + return taskInfo; + } + + public TaskGroup build() { + return new TaskGroup( + taskInfo, + childTasks.stream().map(TaskGroup.Builder::build).collect(Collectors.toList()) + ); + } + } + + public TaskInfo getTaskInfo() { + return task; + } + + public List getChildTasks() { + return childTasks; + } +} + diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java new file mode 100644 index 0000000000000..89f8ed18689d1 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java @@ -0,0 +1,93 @@ +/* + * 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.client.tasks; + +import java.util.Objects; + +/** + * client side version of a {@link org.elasticsearch.tasks.TaskId} + */ +public class TaskId { + + public static final TaskId EMPTY_TASK_ID = new TaskId(); + + protected final String nodeId; + protected final long id; + + protected TaskId() { + nodeId = ""; + id = -1; + } + + public TaskId(String nodeId, long id) { + this.nodeId = nodeId; + this.id = id; + } + + public TaskId(String taskId) { + if (taskId == null) { + throw new IllegalArgumentException("null task id"); + } + String[] s = taskId.split(":"); + if (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); + } + } + + public String getNodeId() { + return nodeId; + } + + public long getId() { + return id; + } + + public boolean isSet() { + return id != -1L; + } + + @Override + public String toString() { + if (isSet()) { + return nodeId + ":" + id; + } else { + return "unset"; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TaskId)) return false; + TaskId taskId = (TaskId) o; + return getId() == taskId.getId() && + getNodeId().equals(taskId.getNodeId()); + } + + @Override + public int hashCode() { + return Objects.hash(getNodeId(), getId()); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java new file mode 100644 index 0000000000000..a0fc6339ff67a --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java @@ -0,0 +1,198 @@ +/* + * 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.client.tasks; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.BiConsumer; + +/** + * client side counterpart of server side + *

+ * {@link org.elasticsearch.tasks.TaskInfo} + */ +public class TaskInfo { + + private TaskId taskId; + private String type; + private String action; + private String description; + private long startTime; + private long runningTimeNanos; + private boolean cancellable; + private TaskId parentTaskId; + private final Map headers = new HashMap<>(); + + /** + * as it is a named object + * in the JSON structure, it requires + * a name in the constructor to cope with signature of: + * {@link ObjectParser#declareNamedObjects(BiConsumer, ObjectParser.NamedObjectParser, ParseField)} + * + * @param taskId the aggregate identifier of a task (node id + task id ) + */ + public TaskInfo(TaskId taskId) { + this.taskId = taskId; + } + + public TaskId getTaskId() { + return taskId; + } + + public String getNodeId() { + return taskId.nodeId; + } + + public String getType() { + return type; + } + + private void setType(String type) { + this.type = type; + } + + public String getAction() { + return action; + } + + private void setAction(String action) { + this.action = action; + } + + public String getDescription() { + return description; + } + + private void setDescription(String description) { + this.description = description; + } + + public long getStartTime() { + return startTime; + } + + private void setStartTime(long startTime) { + this.startTime = startTime; + } + + public long getRunningTimeNanos() { + return runningTimeNanos; + } + + private void setRunningTimeNanos(long runningTimeNanos) { + this.runningTimeNanos = runningTimeNanos; + } + + public boolean isCancellable() { + return cancellable; + } + + private void setCancellable(boolean cancellable) { + this.cancellable = cancellable; + } + + public TaskId getParentTaskId() { + return parentTaskId; + } + + private void setParentTaskId(String parentTaskId) { + this.parentTaskId = new TaskId(parentTaskId); + } + + public Map getHeaders() { + return headers; + } + + private void setHeaders(Map headers) { + this.headers.putAll(headers); + } + + private void noOpParse(Object s) {} + + @Override + public String toString() { + return "TaskInfo{" + + "taskId=" + taskId + + ", type='" + type + '\'' + + ", action='" + action + '\'' + + ", description='" + description + '\'' + + ", startTime=" + startTime + + ", runningTimeNanos=" + runningTimeNanos + + ", cancellable=" + cancellable + + ", parentTaskId=" + parentTaskId + + ", headers=" + headers + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TaskInfo)) return false; + TaskInfo taskInfo = (TaskInfo) o; + return getStartTime() == taskInfo.getStartTime() && + getRunningTimeNanos() == taskInfo.getRunningTimeNanos() && + isCancellable() == taskInfo.isCancellable() && + getTaskId().equals(taskInfo.getTaskId()) && + Objects.equals(getType(), taskInfo.getType()) && + Objects.equals(getAction(), taskInfo.getAction()) && + Objects.equals(getDescription(), taskInfo.getDescription()) && + Objects.equals(getParentTaskId(), taskInfo.getParentTaskId()) && + Objects.equals(getHeaders(), taskInfo.getHeaders()); + } + + @Override + public int hashCode() { + return Objects.hash( + getTaskId(), + getType(), + getAction(), + getDescription(), + getStartTime(), + getRunningTimeNanos(), + isCancellable(), + getParentTaskId(), + getHeaders() + ); + } + + + public static final ObjectParser.NamedObjectParser PARSER; + + static { + ObjectParser parser = new ObjectParser<>("tasks", true, null); + // already provided in constructor: triggering a no-op + parser.declareString(TaskInfo::noOpParse, new ParseField("node")); + // already provided in constructor: triggering a no-op + parser.declareLong(TaskInfo::noOpParse, new ParseField("id")); + parser.declareString(TaskInfo::setType, new ParseField("type")); + parser.declareString(TaskInfo::setAction, new ParseField("action")); + parser.declareString(TaskInfo::setDescription, new ParseField("description")); + parser.declareLong(TaskInfo::setStartTime, new ParseField("start_time_in_millis")); + parser.declareLong(TaskInfo::setRunningTimeNanos, new ParseField("running_time_in_nanos")); + parser.declareBoolean(TaskInfo::setCancellable, new ParseField("cancellable")); + parser.declareString(TaskInfo::setParentTaskId, new ParseField("parent_task_id")); + parser.declareObject(TaskInfo::setHeaders, (p, c) -> p.mapStrings(), new ParseField("headers")); + PARSER = (XContentParser p, Void v, String name) -> parser.parse(p, new TaskInfo(new TaskId(name)), null); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java new file mode 100644 index 0000000000000..208c63ce72c4e --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java @@ -0,0 +1,105 @@ +/* + * 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.client.tasks; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.util.Objects; + +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; + +/** + * client side counterpart of server side + * {@link org.elasticsearch.action.TaskOperationFailure} + */ +public class TaskOperationFailure { + + private static final String TASK_ID = "task_id"; + private static final String NODE_ID = "node_id"; + private static final String REASON = "reason"; + + private final String nodeId; + private final long taskId; + private final Exception reason; + + public TaskOperationFailure(String nodeId, long taskId, Exception reason) { + this.nodeId = nodeId; + this.taskId = taskId; + this.reason = reason; + } + + public String getNodeId() { + return nodeId; + } + + public long getTaskId() { + return taskId; + } + + public Exception getReason() { + return reason; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TaskOperationFailure)) return false; + TaskOperationFailure that = (TaskOperationFailure) o; + return getTaskId() == that.getTaskId() && + getNodeId().equals(that.getNodeId()) && + getReason().equals(that.getReason()); + } + + @Override + public int hashCode() { + return Objects.hash(getNodeId(), getTaskId(), getReason()); + } + + @Override + public String toString() { + return "TaskOperationFailure{" + + "nodeId='" + nodeId + '\'' + + ", taskId=" + taskId + + ", reason=" + reason + + '}'; + } + + public static TaskOperationFailure fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); + } + + private static final ConstructingObjectParser PARSER = + new ConstructingObjectParser<>("task_info", true, constructorObjects -> { + int i = 0; + String nodeId = (String) constructorObjects[i++]; + long taskId = (long) constructorObjects[i++]; + ElasticsearchException reason = (ElasticsearchException) constructorObjects[i]; + return new TaskOperationFailure(nodeId, taskId, reason); + }); + + static { + PARSER.declareString(constructorArg(), new ParseField(NODE_ID)); + PARSER.declareLong(constructorArg(), new ParseField(TASK_ID)); + PARSER.declareObject(constructorArg(), (parser, c) -> ElasticsearchException.fromXContent(parser), new ParseField(REASON)); + } + +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java index 8f2b6cc1d1849..4104792abc6cf 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java @@ -19,21 +19,20 @@ package org.elasticsearch.client; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; +import org.elasticsearch.client.tasks.CancelTasksRequest; +import org.elasticsearch.client.tasks.CancelTasksResponse; import org.elasticsearch.client.tasks.GetTaskRequest; import org.elasticsearch.client.tasks.GetTaskResponse; +import org.elasticsearch.client.tasks.TaskId; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.tasks.TaskId; -import org.elasticsearch.tasks.TaskInfo; import java.io.IOException; import java.util.Collections; @@ -58,12 +57,12 @@ public void testListTasks() throws IOException { assertThat(response.getTasks().size(), greaterThanOrEqualTo(2)); boolean listTasksFound = false; for (TaskGroup taskGroup : response.getTaskGroups()) { - TaskInfo parent = taskGroup.getTaskInfo(); + org.elasticsearch.tasks.TaskInfo parent = taskGroup.getTaskInfo(); if ("cluster:monitor/tasks/lists".equals(parent.getAction())) { assertThat(taskGroup.getChildTasks().size(), equalTo(1)); TaskGroup childGroup = taskGroup.getChildTasks().iterator().next(); assertThat(childGroup.getChildTasks().isEmpty(), equalTo(true)); - TaskInfo child = childGroup.getTaskInfo(); + org.elasticsearch.tasks.TaskInfo child = childGroup.getTaskInfo(); assertThat(child.getAction(), equalTo("cluster:monitor/tasks/lists[n]")); assertThat(child.getParentTaskId(), equalTo(parent.getTaskId())); listTasksFound = true; @@ -117,7 +116,7 @@ public void testGetValidTask() throws Exception { if (gtr.getWaitForCompletion()) { assertTrue(taskResponse.isCompleted()); } - TaskInfo info = taskResponse.getTaskInfo(); + org.elasticsearch.tasks.TaskInfo info = taskResponse.getTaskInfo(); assertTrue(info.isCancellable()); assertEquals("reindex from [source1] to [dest]", info.getDescription()); assertEquals("indices:data/write/reindex", info.getAction()); @@ -142,7 +141,7 @@ public void testCancelTasks() throws IOException { ); // in this case, probably no task will actually be cancelled. // this is ok, that case is covered in TasksIT.testTasksCancellation - TaskInfo firstTask = listResponse.getTasks().get(0); + org.elasticsearch.tasks.TaskInfo firstTask = listResponse.getTasks().get(0); String node = listResponse.getPerNodeTasks().keySet().iterator().next(); CancelTasksRequest cancelTasksRequest = new CancelTasksRequest(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java index 4b7889d3b7e7a..10952ca9fc41d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java @@ -21,7 +21,6 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; import org.elasticsearch.tasks.TaskId; import org.elasticsearch.test.ESTestCase; @@ -36,10 +35,12 @@ public class TasksRequestConvertersTests extends ESTestCase { public void testCancelTasks() { - CancelTasksRequest request = new CancelTasksRequest(); + org.elasticsearch.client.tasks.CancelTasksRequest request = new org.elasticsearch.client.tasks.CancelTasksRequest(); Map expectedParams = new HashMap<>(); - TaskId taskId = new TaskId(randomAlphaOfLength(5), randomNonNegativeLong()); - TaskId parentTaskId = new TaskId(randomAlphaOfLength(5), randomNonNegativeLong()); + org.elasticsearch.client.tasks.TaskId taskId = + new org.elasticsearch.client.tasks.TaskId(randomAlphaOfLength(5), randomNonNegativeLong()); + org.elasticsearch.client.tasks.TaskId parentTaskId = + new org.elasticsearch.client.tasks.TaskId(randomAlphaOfLength(5), randomNonNegativeLong()); request.setTaskId(taskId); request.setParentTaskId(parentTaskId); expectedParams.put("task_id", taskId.toString()); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java index 56a7fce498c2a..6ac77fcc89e76 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java @@ -23,14 +23,14 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.LatchedActionListener; import org.elasticsearch.action.TaskOperationFailure; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest; -import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest; import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse; import org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup; import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.tasks.CancelTasksRequest; +import org.elasticsearch.client.tasks.CancelTasksResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.tasks.TaskId; import org.elasticsearch.tasks.TaskInfo; @@ -80,7 +80,7 @@ public void testListTasks() throws IOException { request.setParentTaskId(new TaskId("parentTaskId", 42)); // <3> // end::list-tasks-request-filter - // tag::list-tasks-request-detailed + // tag::list-tasks-request-detailed~ request.setDetailed(true); // <1> // end::list-tasks-request-detailed @@ -159,7 +159,7 @@ public void testCancelTasks() throws IOException { // end::cancel-tasks-request // tag::cancel-tasks-request-filter - request.setTaskId(new TaskId("nodeId1", 42)); //<1> + request.setTaskId(new org.elasticsearch.client.tasks.TaskId("nodeId1", 42)); //<1> request.setActions("cluster:*"); // <2> request.setNodes("nodeId1", "nodeId2"); // <3> // end::cancel-tasks-request-filter @@ -167,7 +167,7 @@ public void testCancelTasks() throws IOException { } CancelTasksRequest request = new CancelTasksRequest(); - request.setTaskId(TaskId.EMPTY_TASK_ID); + request.setTaskId(org.elasticsearch.client.tasks.TaskId.EMPTY_TASK_ID); // tag::cancel-tasks-execute CancelTasksResponse response = client.tasks().cancel(request, RequestOptions.DEFAULT); @@ -176,18 +176,18 @@ public void testCancelTasks() throws IOException { assertThat(response, notNullValue()); // tag::cancel-tasks-response-tasks - List tasks = response.getTasks(); // <1> + List tasks = response.getTasks(); // <1> // end::cancel-tasks-response-tasks // tag::cancel-tasks-response-calc - Map> perNodeTasks = response.getPerNodeTasks(); // <1> - List groups = response.getTaskGroups(); // <2> + Map> perNodeTasks = response.getPerNodeTasks(); // <1> + List groups = response.getTaskGroups(); // <2> // end::cancel-tasks-response-calc // tag::cancel-tasks-response-failures - List nodeFailures = response.getNodeFailures(); // <1> - List taskFailures = response.getTaskFailures(); // <2> + List nodeFailures = response.getNodeFailures(); // <1> + List taskFailures = response.getTaskFailures(); // <2> // end::cancel-tasks-response-failures assertThat(response.getNodeFailures(), equalTo(emptyList())); From 5680adfb8f79e21d7b323192d8ff8096a6101e14 Mon Sep 17 00:00:00 2001 From: jesinity Date: Wed, 30 Oct 2019 22:00:47 +0100 Subject: [PATCH 2/6] doing the fixes --- .../client/RequestConverters.java | 13 +- .../org/elasticsearch/client/TasksClient.java | 13 +- .../client/TasksRequestConverters.java | 13 +- .../client/tasks/CancelTasksRequest.java | 131 ++++++++------ .../client/tasks/CancelTasksResponse.java | 42 +++-- .../client/tasks/ElasticsearchException.java | 81 +++++---- .../elasticsearch/client/tasks/NodeData.java | 24 +-- .../client/tasks/NodesInfoData.java | 51 ------ .../elasticsearch/client/tasks/TaskGroup.java | 12 +- .../elasticsearch/client/tasks/TaskId.java | 14 +- .../elasticsearch/client/tasks/TaskInfo.java | 103 +++++------ .../client/tasks/TaskOperationFailure.java | 38 ++-- .../org/elasticsearch/client/TasksIT.java | 6 +- .../client/TasksRequestConvertersTests.java | 9 +- .../TasksClientDocumentationIT.java | 15 +- .../tasks/CancelTasksResponseTests.java | 164 ++++++++++++++++++ 16 files changed, 452 insertions(+), 277 deletions(-) delete mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index 093062b85f3b9..0b356007822a1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -87,6 +87,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -1029,14 +1030,22 @@ Params withWaitForCompletion(Boolean waitForCompletion) { } Params withNodes(String[] nodes) { - if (nodes != null && nodes.length > 0) { + return withNodes(Arrays.asList(nodes)); + } + + Params withNodes(List nodes) { + if (nodes != null && nodes.size() > 0) { return putParam("nodes", String.join(",", nodes)); } return this; } Params withActions(String[] actions) { - if (actions != null && actions.length > 0) { + return withActions(Arrays.asList(actions)); + } + + Params withActions(List actions) { + if (actions != null && actions.size() > 0) { return putParam("actions", String.join(",", actions)); } return this; diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java index 2c9f461b5d246..7ed38ca2126e0 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksClient.java @@ -102,7 +102,17 @@ public Cancellable getAsync(GetTaskRequest request, RequestOptions options, GetTaskResponse::fromXContent, listener); } - + /** + * Cancel one or more cluster tasks using the Task Management API. + * + * See + * Task Management API on elastic.co + * @param cancelTasksRequest the request + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response + * @throws IOException in case there is a problem sending the request or parsing back the response + * + */ public CancelTasksResponse cancel(CancelTasksRequest cancelTasksRequest, RequestOptions options ) throws IOException { return restHighLevelClient.performRequestAndParseEntity( cancelTasksRequest, @@ -125,7 +135,6 @@ public CancelTasksResponse cancel(CancelTasksRequest cancelTasksRequest, Request */ public Cancellable cancelAsync(CancelTasksRequest cancelTasksRequest, RequestOptions options, ActionListener listener) { - return restHighLevelClient.performRequestAsyncAndParseEntity( cancelTasksRequest, TasksRequestConverters::cancelTasks, diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java index 4a78c561db07b..9099e8a854121 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/TasksRequestConverters.java @@ -30,14 +30,15 @@ final class TasksRequestConverters { private TasksRequestConverters() {} - static Request cancelTasks(CancelTasksRequest cancelTasksRequest) { + static Request cancelTasks(CancelTasksRequest req) { Request request = new Request(HttpPost.METHOD_NAME, "/_tasks/_cancel"); RequestConverters.Params params = new RequestConverters.Params(); - params.withTimeout(cancelTasksRequest.getTimeout()) - .withTaskId(cancelTasksRequest.getTaskId()) - .withNodes(cancelTasksRequest.getNodes()) - .withParentTaskId(cancelTasksRequest.getParentTaskId()) - .withActions(cancelTasksRequest.getActions()); + req.getTimeout().ifPresent(params::withTimeout); + req.getTaskId().ifPresent(params::withTaskId); + req.getParentTaskId().ifPresent(params::withParentTaskId); + params + .withNodes(req.getNodes()) + .withActions(req.getActions()); request.addParameters(params.asMap()); return request; } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java index 8da965a6f018e..c1a276bc675ba 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java @@ -21,110 +21,133 @@ import org.elasticsearch.client.Validatable; import org.elasticsearch.common.unit.TimeValue; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; +import java.util.Optional; public class CancelTasksRequest implements Validatable { - public static final String[] EMPTY_ARRAY = new String[0]; - public static final String[] ALL_ACTIONS = EMPTY_ARRAY; - public static final String[] ALL_NODES = EMPTY_ARRAY; - private String[] nodes = ALL_NODES; - private TimeValue timeout; - private String[] actions = ALL_ACTIONS; - private TaskId parentTaskId = TaskId.EMPTY_TASK_ID; - private TaskId taskId = TaskId.EMPTY_TASK_ID; - private String reason = ""; - - public final CancelTasksRequest setNodes(String... nodes) { - this.nodes = nodes; + private final List nodes = new ArrayList<>(); + private final List actions = new ArrayList<>(); + private Optional timeout = Optional.empty(); + private Optional parentTaskId = Optional.empty(); + private Optional taskId = Optional.empty(); + + CancelTasksRequest(){} + + CancelTasksRequest setNodes(List nodes) { + this.nodes.addAll(nodes); return this; } - public String[] getNodes() { + public List getNodes() { return nodes; } - public CancelTasksRequest setTimeout(TimeValue timeout) { - this.timeout = timeout; - return this; - } - - public final CancelTasksRequest setTimeout(String timeout) { - this.timeout = TimeValue.parseTimeValue(timeout, null, getClass().getSimpleName() + ".timeout"); - return this; + void setTimeout(TimeValue timeout) { + this.timeout = Optional.of(timeout); } - public TimeValue getTimeout() { + public Optional getTimeout() { return timeout; } - public CancelTasksRequest setActions(String... actions) { - this.actions = actions; + CancelTasksRequest setActions(List actions) { + this.actions.addAll(actions); return this; } - public String[] getActions() { + public List getActions() { return actions; } - public CancelTasksRequest setParentTaskId(TaskId parentTaskId) { - this.parentTaskId = parentTaskId; - return this; + void setParentTaskId(TaskId parentTaskId) { + this.parentTaskId = Optional.of(parentTaskId); } - public TaskId getParentTaskId() { + public Optional getParentTaskId() { return parentTaskId; } - public CancelTasksRequest setTaskId(TaskId taskId) { - this.taskId = taskId; - return this; + void setTaskId(TaskId taskId) { + this.taskId = Optional.of(taskId); } - public TaskId getTaskId() { + public Optional getTaskId() { return taskId; } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CancelTasksRequest)) return false; CancelTasksRequest that = (CancelTasksRequest) o; - return Arrays.equals(getNodes(), that.getNodes()) && + return Objects.equals(getNodes(), that.getNodes()) && + Objects.equals(getActions(), that.getActions()) && Objects.equals(getTimeout(), that.getTimeout()) && - Arrays.equals(getActions(), that.getActions()) && Objects.equals(getParentTaskId(), that.getParentTaskId()) && - Objects.equals(getTaskId(), that.getTaskId()) && - Objects.equals(getReason(), that.getReason()); + Objects.equals(getTaskId(), that.getTaskId()) ; } @Override public int hashCode() { - int result = Objects.hash(getTimeout(), getParentTaskId(), getTaskId(), getReason()); - result = 31 * result + Arrays.hashCode(getNodes()); - result = 31 * result + Arrays.hashCode(getActions()); - return result; + return Objects.hash(getNodes(), getActions(), getTimeout(), getParentTaskId(), getTaskId()); } @Override public String toString() { return "CancelTasksRequest{" + - "nodes=" + Arrays.toString(nodes) + + "nodes=" + nodes + + ", actions=" + actions + ", timeout=" + timeout + - ", actions=" + Arrays.toString(actions) + ", parentTaskId=" + parentTaskId + ", taskId=" + taskId + - ", reason='" + reason + '\'' + '}'; } + + public static class Builder { + private Optional timeout = Optional.empty(); + private Optional taskId = Optional.empty(); + private Optional parentTaskId = Optional.empty(); + private List actionsFilter = new ArrayList<>(); + private List nodesFilter = new ArrayList<>(); + + public Builder withTimeout(TimeValue timeout){ + this.timeout = Optional.of(timeout); + return this; + } + + public Builder withTaskId(TaskId taskId){ + this.taskId = Optional.of(taskId); + return this; + } + + public Builder withParentTaskId(TaskId taskId){ + this.parentTaskId = Optional.of(taskId); + return this; + } + + public Builder withActionsFiltered(List actions){ + this.actionsFilter.clear(); + this.actionsFilter.addAll(actions); + return this; + } + + public Builder withNodesFiltered(List nodes){ + this.nodesFilter.clear(); + this.nodesFilter.addAll(nodes); + return this; + } + + public CancelTasksRequest build() { + CancelTasksRequest request = new CancelTasksRequest(); + timeout.ifPresent(request::setTimeout); + taskId.ifPresent(request::setTaskId); + parentTaskId.ifPresent(request::setParentTaskId); + request.setNodes(nodesFilter); + request.setActions(actionsFilter); + return request; + } + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java index 9750367c8d6eb..d9053f17b9882 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java @@ -35,31 +35,38 @@ import static java.util.stream.Collectors.toList; import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; +/** + * cancel tasks response that contains + * - task failures + * - node failures + * - tasks + */ public class CancelTasksResponse { - private final NodesInfoData nodesInfoData; private final List taskFailures = new ArrayList<>(); private final List nodeFailures = new ArrayList<>(); + private final List nodesInfoData = new ArrayList<>(); private final List tasks = new ArrayList<>(); private final List taskGroups = new ArrayList<>(); - public CancelTasksResponse(NodesInfoData nodesInfoData, - List taskFailures, - List nodeFailures) { - this.nodesInfoData = nodesInfoData; - if (taskFailures!= null){ + CancelTasksResponse(List nodesInfoData, + List taskFailures, + List nodeFailures) { + if (taskFailures != null) { this.taskFailures.addAll(taskFailures); } - if (nodeFailures!=null) { + if (nodeFailures != null) { this.nodeFailures.addAll(nodeFailures); } - this.tasks.addAll(nodesInfoData - .getNodesInfoData() + if (nodesInfoData != null) { + this.nodesInfoData.addAll(nodesInfoData); + } + this.tasks.addAll(this + .nodesInfoData .stream() .flatMap(nodeData -> nodeData.getTasks().stream()) .collect(toList()) ); - this.taskGroups.addAll(buildTaskGroups()); } @@ -74,7 +81,7 @@ private List buildTaskGroups() { // Now go through all task group builders and add children to their parents for (TaskGroup.Builder taskGroup : taskGroups.values()) { TaskId parentTaskId = taskGroup.getTaskInfo().getParentTaskId(); - if (parentTaskId.isSet()) { + if (parentTaskId != null) { TaskGroup.Builder parentTask = taskGroups.get(parentTaskId); if (parentTask != null) { // we found parent in the list of tasks - add it to the parent list @@ -91,10 +98,6 @@ private List buildTaskGroups() { return Collections.unmodifiableList(topLevelTasks.stream().map(TaskGroup.Builder::build).collect(Collectors.toList())); } - public NodesInfoData getNodesInfoData() { - return nodesInfoData; - } - public List getTasks() { return tasks; } @@ -122,7 +125,7 @@ public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CancelTasksResponse)) return false; CancelTasksResponse response = (CancelTasksResponse) o; - return getNodesInfoData().equals(response.getNodesInfoData()) && + return nodesInfoData.equals(response.nodesInfoData) && Objects.equals(getTaskFailures(), response.getTaskFailures()) && Objects.equals(getNodeFailures(), response.getNodeFailures()) && Objects.equals(getTasks(), response.getTasks()) && @@ -131,7 +134,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(getNodesInfoData(), getTaskFailures(), getNodeFailures(), getTasks(), getTaskGroups()); + return Objects.hash(nodesInfoData, getTaskFailures(), getNodeFailures(), getTasks(), getTaskGroups()); } public static CancelTasksResponse fromXContent(final XContentParser parser) throws IOException { @@ -159,7 +162,8 @@ public String toString() { List tasksFailures = (List) constructingObjects[i++]; @SuppressWarnings("unchecked") List nodeFailures = (List) constructingObjects[i++]; - NodesInfoData nodesInfoData = (NodesInfoData) constructingObjects[i]; + @SuppressWarnings("unchecked") + List nodesInfoData = (List) constructingObjects[i]; return new CancelTasksResponse(nodesInfoData, tasksFailures, nodeFailures); }); @@ -167,7 +171,7 @@ public String toString() { TaskOperationFailure.fromXContent(p), new ParseField("task_failures")); parser.declareObjectArray(optionalConstructorArg(), (p, c) -> ElasticsearchException.fromXContent(p), new ParseField("node_failures")); - parser.declareObject(optionalConstructorArg(), NodesInfoData.PARSER, new ParseField("nodes")); + parser.declareNamedObjects(optionalConstructorArg(), NodeData.PARSER, new ParseField("nodes")); PARSER = parser; } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java index cac6d4c9826fd..d5e0eb8f64ee2 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java @@ -21,7 +21,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,8 +31,9 @@ /** * client side counterpart of server side * {@link org.elasticsearch.ElasticsearchException} + * It wraps the same content but it is not throwable. */ -public class ElasticsearchException extends RuntimeException { +public class ElasticsearchException { private static final String TYPE = "type"; private static final String REASON = "reason"; @@ -42,15 +42,32 @@ public class ElasticsearchException extends RuntimeException { private static final String STACK_TRACE = "stack_trace"; private static final String HEADER = "header"; private static final String ROOT_CAUSE = "root_cause"; - private final Map> metadata = new HashMap<>(); + + private String msg; + private ElasticsearchException cause; private final Map> headers = new HashMap<>(); - private Object[] args; + private final List suppressed = new ArrayList<>(); - public ElasticsearchException(){} + ElasticsearchException(String msg) { + this.msg = msg; + this.cause = null; + } - public ElasticsearchException(String msg, Throwable cause, Object... args) { - super(msg,cause); - this.args = args; + ElasticsearchException(String msg, ElasticsearchException cause) { + this.msg = msg; + this.cause = cause; + } + + public String getMsg() { + return msg; + } + + public ElasticsearchException getCause() { + return cause; + } + + public List getSuppressed() { + return suppressed; } /** @@ -60,19 +77,18 @@ public ElasticsearchException(String msg, Throwable cause, Object... args) { * tree structure of the cause, returning it as a tree structure of {@link ElasticsearchException} * instances. */ - public static ElasticsearchException fromXContent(XContentParser parser) throws IOException { + static ElasticsearchException fromXContent(XContentParser parser) throws IOException { XContentParser.Token token = parser.nextToken(); ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); return innerFromXContent(parser, false); } - public static ElasticsearchException innerFromXContent(XContentParser parser, boolean parseRootCauses) throws IOException { + private static ElasticsearchException innerFromXContent(XContentParser parser, boolean parseRootCauses) throws IOException { XContentParser.Token token = parser.currentToken(); ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); String type = null, reason = null, stack = null; ElasticsearchException cause = null; - Map> metadata = new HashMap<>(); Map> headers = new HashMap<>(); List rootCauses = new ArrayList<>(); List suppressed = new ArrayList<>(); @@ -88,8 +104,6 @@ public static ElasticsearchException innerFromXContent(XContentParser parser, bo reason = parser.text(); } else if (STACK_TRACE.equals(currentFieldName)) { stack = parser.text(); - } else if (token == XContentParser.Token.VALUE_STRING) { - metadata.put(currentFieldName, Collections.singletonList(parser.text())); } } else if (token == XContentParser.Token.START_OBJECT) { if (CAUSED_BY.equals(currentFieldName)) { @@ -142,32 +156,20 @@ public static ElasticsearchException innerFromXContent(XContentParser parser, bo parser.skipChildren(); } } - if (values.size() > 0) { - if (metadata.containsKey(currentFieldName)) { - values.addAll(metadata.get(currentFieldName)); - } - metadata.put(currentFieldName, values); - } } } } ElasticsearchException e = new ElasticsearchException(buildMessage(type, reason, stack), cause); - for (Map.Entry> entry : metadata.entrySet()) { - e.addMetadata("es." + entry.getKey(), entry.getValue()); - } for (Map.Entry> header : headers.entrySet()) { e.addHeader(header.getKey(), header.getValue()); } // Adds root causes as suppressed exception. This way they are not lost // after parsing and can be retrieved using getSuppressed() method. - for (ElasticsearchException rootCause : rootCauses) { - e.addSuppressed(rootCause); - } - for (ElasticsearchException s : suppressed) { - e.addSuppressed(s); - } + e.suppressed.addAll(rootCauses); + e.suppressed.addAll(suppressed); + return e; } @@ -176,8 +178,8 @@ private void addHeader(String key, List value) { } - private void addMetadata(String s, List value) { - metadata.put(s,value); + public Map> getHeaders() { + return headers; } static String buildMessage(String type, String reason, String stack) { @@ -191,32 +193,29 @@ static String buildMessage(String type, String reason, String stack) { return message.toString(); } - @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ElasticsearchException)) return false; ElasticsearchException that = (ElasticsearchException) o; - return Objects.equals(metadata, that.metadata) && - Objects.equals(headers, that.headers) && - Objects.equals(getCause(), that.getCause()) ; + return Objects.equals(getMsg(), that.getMsg()) && + Objects.equals(getCause(), that.getCause()) && + Objects.equals(getHeaders(), that.getHeaders()) && + Objects.equals(getSuppressed(), that.getSuppressed()); } @Override public int hashCode() { - return Objects.hash(metadata, headers,getCause()); + return Objects.hash(getMsg(), getCause(), getHeaders(), getSuppressed()); } @Override public String toString() { return "ElasticsearchException{" + - "cause=" + getCause() + - "metadata=" + metadata + + "msg='" + msg + '\'' + + ", cause=" + cause + ", headers=" + headers + + ", suppressed=" + suppressed + '}'; } - - public Object[] getArgs() { - return args; - } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java index a0e3cef658ec0..2bb65db02d916 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java @@ -28,7 +28,7 @@ import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; -public class NodeData { +class NodeData { private String nodeId; private String name; @@ -47,11 +47,11 @@ public class NodeData { * * @param nodeId the string identifier of a node */ - private NodeData(String nodeId) { + NodeData(String nodeId) { this.nodeId = nodeId; } - private void setName(String name) { + void setName(String name) { this.name = name; } @@ -61,19 +61,19 @@ public void setAttributes(Map attributes) { } } - private void setTransportAddress(String transportAddress) { + void setTransportAddress(String transportAddress) { this.transportAddress = transportAddress; } - private void setHost(String host) { + void setHost(String host) { this.host = host; } - private void setIp(String ip) { + void setIp(String ip) { this.ip = ip; } - private void setRoles(List roles) { + void setRoles(List roles) { if(roles!=null){ this.roles.addAll(roles); } @@ -111,7 +111,7 @@ public List getTasks() { return tasks; } - private void setTasks(List tasks) { + void setTasks(List tasks) { if(tasks!=null){ this.tasks.addAll(tasks); } @@ -160,10 +160,10 @@ public int hashCode() { parser.declareString(NodeData::setIp, new ParseField("ip")); parser.declareStringArray(NodeData::setRoles, new ParseField("roles")); parser.declareField(NodeData::setAttributes, - (p, c) -> p.mapStrings(), - new ParseField("attributes"), - ObjectParser.ValueType.OBJECT); + (p, c) -> p.mapStrings(), + new ParseField("attributes"), + ObjectParser.ValueType.OBJECT); parser.declareNamedObjects(NodeData::setTasks, TaskInfo.PARSER, new ParseField("tasks")); - PARSER = (XContentParser p, Void v, String name) -> parser.parse(p, new NodeData(name), null); + PARSER = (XContentParser p, Void v, String nodeId) -> parser.parse(p, new NodeData(nodeId), null); } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java deleted file mode 100644 index d39e84aee919e..0000000000000 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodesInfoData.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.client.tasks; - -import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.xcontent.ObjectParser; - -import java.util.ArrayList; -import java.util.List; - -/** - * Holder of data created out of a {@link CancelTasksResponse} - */ -public class NodesInfoData { - - private final List nodesInfoData = new ArrayList<>(); - - NodesInfoData() {} - - public List getNodesInfoData() { - return nodesInfoData; - } - - private void setNodesInfoData(List nodesInfoData) { - if(nodesInfoData!=null){ - this.nodesInfoData.addAll(nodesInfoData); - } - } - - public static final ObjectParser PARSER = new ObjectParser<>("nodes", NodesInfoData::new); - - static { - PARSER.declareNamedObjects(NodesInfoData::setNodesInfoData, NodeData.PARSER, new ParseField("nodes")); - } -} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java index f13ae2160f369..6fce60a111140 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskGroup.java @@ -32,6 +32,14 @@ public class TaskGroup { private final TaskInfo task; + @Override + public String toString() { + return "TaskGroup{" + + "task=" + task + + ", childTasks=" + childTasks + + '}'; + } + private final List childTasks = new ArrayList<>(); public TaskGroup(TaskInfo task, List childTasks) { @@ -48,8 +56,8 @@ public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TaskGroup)) return false; TaskGroup taskGroup = (TaskGroup) o; - return task.equals(taskGroup.task) && - getChildTasks().equals(taskGroup.getChildTasks()); + return Objects.equals(task, taskGroup.task) && + Objects.equals(getChildTasks(), taskGroup.getChildTasks()); } @Override diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java index 89f8ed18689d1..c0dc16f92d475 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskId.java @@ -25,21 +25,18 @@ */ public class TaskId { - public static final TaskId EMPTY_TASK_ID = new TaskId(); - protected final String nodeId; protected final long id; - protected TaskId() { - nodeId = ""; - id = -1; - } - public TaskId(String nodeId, long id) { this.nodeId = nodeId; this.id = id; } + /** + * accepts a raw format task id + * @param taskId expected to be nodeid:taskId + */ public TaskId(String taskId) { if (taskId == null) { throw new IllegalArgumentException("null task id"); @@ -77,13 +74,14 @@ public String toString() { } } + @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TaskId)) return false; TaskId taskId = (TaskId) o; return getId() == taskId.getId() && - getNodeId().equals(taskId.getNodeId()); + Objects.equals(getNodeId(), taskId.getNodeId()); } @Override diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java index a0fc6339ff67a..657795d98dcba 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java @@ -27,6 +27,7 @@ import java.util.Objects; import java.util.function.BiConsumer; + /** * client side counterpart of server side *

@@ -42,6 +43,7 @@ public class TaskInfo { private long runningTimeNanos; private boolean cancellable; private TaskId parentTaskId; + private final Map status = new HashMap<>(); private final Map headers = new HashMap<>(); /** @@ -68,7 +70,7 @@ public String getType() { return type; } - private void setType(String type) { + void setType(String type) { this.type = type; } @@ -76,7 +78,7 @@ public String getAction() { return action; } - private void setAction(String action) { + void setAction(String action) { this.action = action; } @@ -84,7 +86,7 @@ public String getDescription() { return description; } - private void setDescription(String description) { + void setDescription(String description) { this.description = description; } @@ -92,7 +94,7 @@ public long getStartTime() { return startTime; } - private void setStartTime(long startTime) { + void setStartTime(long startTime) { this.startTime = startTime; } @@ -100,7 +102,7 @@ public long getRunningTimeNanos() { return runningTimeNanos; } - private void setRunningTimeNanos(long runningTimeNanos) { + void setRunningTimeNanos(long runningTimeNanos) { this.runningTimeNanos = runningTimeNanos; } @@ -108,7 +110,7 @@ public boolean isCancellable() { return cancellable; } - private void setCancellable(boolean cancellable) { + void setCancellable(boolean cancellable) { this.cancellable = cancellable; } @@ -116,7 +118,7 @@ public TaskId getParentTaskId() { return parentTaskId; } - private void setParentTaskId(String parentTaskId) { + void setParentTaskId(String parentTaskId) { this.parentTaskId = new TaskId(parentTaskId); } @@ -124,25 +126,37 @@ public Map getHeaders() { return headers; } - private void setHeaders(Map headers) { + void setHeaders(Map headers) { this.headers.putAll(headers); } - private void noOpParse(Object s) {} + void setStatus(Map status) { + this.status.putAll(status); + } - @Override - public String toString() { - return "TaskInfo{" + - "taskId=" + taskId + - ", type='" + type + '\'' + - ", action='" + action + '\'' + - ", description='" + description + '\'' + - ", startTime=" + startTime + - ", runningTimeNanos=" + runningTimeNanos + - ", cancellable=" + cancellable + - ", parentTaskId=" + parentTaskId + - ", headers=" + headers + - '}'; + void noOpParse(Object s) {} + + + + + public static final ObjectParser.NamedObjectParser PARSER; + + static { + ObjectParser parser = new ObjectParser<>("tasks", true, null); + // already provided in constructor: triggering a no-op + parser.declareString(TaskInfo::noOpParse, new ParseField("node")); + // already provided in constructor: triggering a no-op + parser.declareLong(TaskInfo::noOpParse, new ParseField("id")); + parser.declareString(TaskInfo::setType, new ParseField("type")); + parser.declareString(TaskInfo::setAction, new ParseField("action")); + parser.declareObject(TaskInfo::setStatus, (p, c) -> p.map(), new ParseField("status")); + parser.declareString(TaskInfo::setDescription, new ParseField("description")); + parser.declareLong(TaskInfo::setStartTime, new ParseField("start_time_in_millis")); + parser.declareLong(TaskInfo::setRunningTimeNanos, new ParseField("running_time_in_nanos")); + parser.declareBoolean(TaskInfo::setCancellable, new ParseField("cancellable")); + parser.declareString(TaskInfo::setParentTaskId, new ParseField("parent_task_id")); + parser.declareObject(TaskInfo::setHeaders, (p, c) -> p.mapStrings(), new ParseField("headers")); + PARSER = (XContentParser p, Void v, String name) -> parser.parse(p, new TaskInfo(new TaskId(name)), null); } @Override @@ -153,46 +167,37 @@ public boolean equals(Object o) { return getStartTime() == taskInfo.getStartTime() && getRunningTimeNanos() == taskInfo.getRunningTimeNanos() && isCancellable() == taskInfo.isCancellable() && - getTaskId().equals(taskInfo.getTaskId()) && + Objects.equals(getTaskId(), taskInfo.getTaskId()) && Objects.equals(getType(), taskInfo.getType()) && Objects.equals(getAction(), taskInfo.getAction()) && Objects.equals(getDescription(), taskInfo.getDescription()) && Objects.equals(getParentTaskId(), taskInfo.getParentTaskId()) && + Objects.equals(status, taskInfo.status) && Objects.equals(getHeaders(), taskInfo.getHeaders()); } @Override public int hashCode() { return Objects.hash( - getTaskId(), - getType(), - getAction(), - getDescription(), - getStartTime(), - getRunningTimeNanos(), - isCancellable(), - getParentTaskId(), - getHeaders() + getTaskId(), getType(), getAction(), getDescription(), getStartTime(), + getRunningTimeNanos(), isCancellable(), getParentTaskId(), status, getHeaders() ); } - public static final ObjectParser.NamedObjectParser PARSER; - - static { - ObjectParser parser = new ObjectParser<>("tasks", true, null); - // already provided in constructor: triggering a no-op - parser.declareString(TaskInfo::noOpParse, new ParseField("node")); - // already provided in constructor: triggering a no-op - parser.declareLong(TaskInfo::noOpParse, new ParseField("id")); - parser.declareString(TaskInfo::setType, new ParseField("type")); - parser.declareString(TaskInfo::setAction, new ParseField("action")); - parser.declareString(TaskInfo::setDescription, new ParseField("description")); - parser.declareLong(TaskInfo::setStartTime, new ParseField("start_time_in_millis")); - parser.declareLong(TaskInfo::setRunningTimeNanos, new ParseField("running_time_in_nanos")); - parser.declareBoolean(TaskInfo::setCancellable, new ParseField("cancellable")); - parser.declareString(TaskInfo::setParentTaskId, new ParseField("parent_task_id")); - parser.declareObject(TaskInfo::setHeaders, (p, c) -> p.mapStrings(), new ParseField("headers")); - PARSER = (XContentParser p, Void v, String name) -> parser.parse(p, new TaskInfo(new TaskId(name)), null); + @Override + public String toString() { + return "TaskInfo{" + + "taskId=" + taskId + + ", type='" + type + '\'' + + ", action='" + action + '\'' + + ", description='" + description + '\'' + + ", startTime=" + startTime + + ", runningTimeNanos=" + runningTimeNanos + + ", cancellable=" + cancellable + + ", parentTaskId=" + parentTaskId + + ", status=" + status + + ", headers=" + headers + + '}'; } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java index 208c63ce72c4e..8aa222da04cb6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskOperationFailure.java @@ -18,7 +18,6 @@ */ package org.elasticsearch.client.tasks; -import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentParser; @@ -33,17 +32,15 @@ */ public class TaskOperationFailure { - private static final String TASK_ID = "task_id"; - private static final String NODE_ID = "node_id"; - private static final String REASON = "reason"; - private final String nodeId; private final long taskId; - private final Exception reason; + private final ElasticsearchException reason; + private final String status; - public TaskOperationFailure(String nodeId, long taskId, Exception reason) { + public TaskOperationFailure(String nodeId, long taskId,String status, ElasticsearchException reason) { this.nodeId = nodeId; this.taskId = taskId; + this.status = status; this.reason = reason; } @@ -55,34 +52,38 @@ public long getTaskId() { return taskId; } - public Exception getReason() { + public ElasticsearchException getReason() { return reason; } + public String getStatus() { + return status; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof TaskOperationFailure)) return false; TaskOperationFailure that = (TaskOperationFailure) o; return getTaskId() == that.getTaskId() && - getNodeId().equals(that.getNodeId()) && - getReason().equals(that.getReason()); + Objects.equals(getNodeId(), that.getNodeId()) && + Objects.equals(getReason(), that.getReason()) && + Objects.equals(getStatus(), that.getStatus()); } @Override public int hashCode() { - return Objects.hash(getNodeId(), getTaskId(), getReason()); + return Objects.hash(getNodeId(), getTaskId(), getReason(), getStatus()); } - @Override public String toString() { return "TaskOperationFailure{" + "nodeId='" + nodeId + '\'' + ", taskId=" + taskId + ", reason=" + reason + + ", status='" + status + '\'' + '}'; } - public static TaskOperationFailure fromXContent(XContentParser parser) { return PARSER.apply(parser, null); } @@ -92,14 +93,15 @@ public static TaskOperationFailure fromXContent(XContentParser parser) { int i = 0; String nodeId = (String) constructorObjects[i++]; long taskId = (long) constructorObjects[i++]; + String status = (String) constructorObjects[i++]; ElasticsearchException reason = (ElasticsearchException) constructorObjects[i]; - return new TaskOperationFailure(nodeId, taskId, reason); + return new TaskOperationFailure(nodeId, taskId, status, reason); }); static { - PARSER.declareString(constructorArg(), new ParseField(NODE_ID)); - PARSER.declareLong(constructorArg(), new ParseField(TASK_ID)); - PARSER.declareObject(constructorArg(), (parser, c) -> ElasticsearchException.fromXContent(parser), new ParseField(REASON)); + PARSER.declareString(constructorArg(), new ParseField("node_id")); + PARSER.declareLong(constructorArg(), new ParseField("task_id")); + PARSER.declareString(constructorArg(), new ParseField("status")); + PARSER.declareObject(constructorArg(), (parser, c) -> ElasticsearchException.fromXContent(parser), new ParseField("reason")); } - } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java index 4104792abc6cf..59183dbf0c0f2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksIT.java @@ -144,9 +144,9 @@ public void testCancelTasks() throws IOException { org.elasticsearch.tasks.TaskInfo firstTask = listResponse.getTasks().get(0); String node = listResponse.getPerNodeTasks().keySet().iterator().next(); - CancelTasksRequest cancelTasksRequest = new CancelTasksRequest(); - cancelTasksRequest.setTaskId(new TaskId(node, firstTask.getId())); - cancelTasksRequest.setReason("testreason"); + CancelTasksRequest cancelTasksRequest = new CancelTasksRequest.Builder().withTaskId( + new TaskId(node, firstTask.getId()) + ).build(); CancelTasksResponse response = execute(cancelTasksRequest, highLevelClient().tasks()::cancel, highLevelClient().tasks()::cancelAsync); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java index 10952ca9fc41d..14c1e0085a67c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java @@ -26,6 +26,7 @@ import org.elasticsearch.test.ESTestCase; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.hamcrest.CoreMatchers.equalTo; @@ -35,14 +36,16 @@ public class TasksRequestConvertersTests extends ESTestCase { public void testCancelTasks() { - org.elasticsearch.client.tasks.CancelTasksRequest request = new org.elasticsearch.client.tasks.CancelTasksRequest(); Map expectedParams = new HashMap<>(); org.elasticsearch.client.tasks.TaskId taskId = new org.elasticsearch.client.tasks.TaskId(randomAlphaOfLength(5), randomNonNegativeLong()); org.elasticsearch.client.tasks.TaskId parentTaskId = new org.elasticsearch.client.tasks.TaskId(randomAlphaOfLength(5), randomNonNegativeLong()); - request.setTaskId(taskId); - request.setParentTaskId(parentTaskId); + org.elasticsearch.client.tasks.CancelTasksRequest request = + new org.elasticsearch.client.tasks.CancelTasksRequest.Builder() + .withTaskId(taskId) + .withParentTaskId(parentTaskId) + .build(); expectedParams.put("task_id", taskId.toString()); expectedParams.put("parent_task_id", parentTaskId.toString()); Request httpRequest = TasksRequestConverters.cancelTasks(request); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java index 6ac77fcc89e76..893f6298f17e7 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java @@ -155,19 +155,20 @@ public void testCancelTasks() throws IOException { RestHighLevelClient client = highLevelClient(); { // tag::cancel-tasks-request - CancelTasksRequest request = new CancelTasksRequest(); + CancelTasksRequest request = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder() + .withNodesFiltered(List.of("nodeId1", "nodeId2")) + .withActionsFiltered(List.of("cluster:*")) + .build(); // end::cancel-tasks-request // tag::cancel-tasks-request-filter - request.setTaskId(new org.elasticsearch.client.tasks.TaskId("nodeId1", 42)); //<1> - request.setActions("cluster:*"); // <2> - request.setNodes("nodeId1", "nodeId2"); // <3> + // request.setTaskId(new org.elasticsearch.client.tasks.TaskId("nodeId1", 42)); //<1> // end::cancel-tasks-request-filter } - CancelTasksRequest request = new CancelTasksRequest(); - request.setTaskId(org.elasticsearch.client.tasks.TaskId.EMPTY_TASK_ID); + CancelTasksRequest request = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder().build(); + //request.setTaskId(org.elasticsearch.client.tasks.TaskId.EMPTY_TASK_ID); // tag::cancel-tasks-execute CancelTasksResponse response = client.tasks().cancel(request, RequestOptions.DEFAULT); @@ -198,7 +199,7 @@ public void testAsyncCancelTasks() throws InterruptedException { RestHighLevelClient client = highLevelClient(); { - CancelTasksRequest request = new CancelTasksRequest(); + CancelTasksRequest request = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder().build(); // tag::cancel-tasks-execute-listener ActionListener listener = diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java new file mode 100644 index 0000000000000..b363e7e492014 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java @@ -0,0 +1,164 @@ +/* + * 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.client.tasks; + +import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CancelTasksResponseTests extends ESTestCase { + + String response = "{\n" + + " \"node_failures\" : [\n" + + " {\n" + + " \"type\" : \"failed_node_exception\",\n" + + " \"reason\" : \"Failed node [AAA]\",\n" + + " \"node_id\" : \"AAA\",\n" + + " \"caused_by\" : {\n" + + " \"type\" : \"no_such_node_exception\",\n" + + " \"reason\" : \"No such node [AAA]\",\n" + + " \"node_id\" : \"AAA\"\n" + + " }\n" + + " }\n" + + " ]," + + " \"task_failures\" : [\n"+ + " {\n"+ + " \"task_id\" : 1186,\n"+ + " \"node_id\" : \"area51node\",\n"+ + " \"status\" : \"INTERNAL_SERVER_ERROR\",\n"+ + " \"reason\" : {\n"+ + " \"type\" : \"illegal_state_exception\",\n"+ + " \"reason\" : \"task with id 1186 is already cancelled\"\n"+ + " }\n"+ + " }\n"+ + " ],\n"+ + " \"nodes\" : {\n" + + " \"BBB\" : {\n" + + " \"name\" : \"instance-0000000004\",\n" + + " \"transport_address\" : \"192.168.1.1:19987\",\n" + + " \"host\" : \"192.168.1.1\",\n" + + " \"ip\" : \"192.168.1.1\",\n" + + " \"roles\" : [\n" + + " \"master\",\n" + + " \"data\",\n" + + " \"ingest\"\n" + + " ],\n" + + " \"attributes\" : {\n" + + " \"logical_availability_zone\" : \"zone-0\",\n" + + " \"server_name\" : \"upupaPowerdome\",\n" + + " \"availability_zone\" : \"us-east-1e\",\n" + + " \"region\" : \"ita-molise-1\" \n" + + " },\n" + + " \"tasks\" : {\n" + + " \"BBB:1481971\" : {\n" + + " \"node\" : \"BBB\",\n" + + " \"id\" : 1481971,\n" + + " \"type\" : \"transport\",\n" + + " \"action\" : \"indices:data/write/reindex\",\n" + + " \"status\" : { \n" + + " \"time\": \"now\",\n"+ + " \"node_count\" : [1,2,3],\n"+ + " \"node_stats\" : [[1,2],[3,4]]\n"+ + " },\n" + + " \"start_time_in_millis\" : 1565108484002,\n" + + " \"running_time_in_nanos\" : 18328639067,\n" + + " \"cancellable\" : true,\n" + + " \"headers\" : { }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + + public void testFromXContent() throws IOException { + + XContentParser parser = JsonXContent.jsonXContent.createParser( + xContentRegistry(), + LoggingDeprecationHandler.INSTANCE, + response); + + CancelTasksResponse response = CancelTasksResponse.fromXContent(parser); + + NodeData nodeData = new NodeData("BBB"); + nodeData.setName("instance-0000000004"); + nodeData.setTransportAddress("192.168.1.1:19987"); + nodeData.setHost("192.168.1.1"); + nodeData.setIp("192.168.1.1"); + nodeData.setRoles(List.of("master", "data", "ingest")); + nodeData.setAttributes( + Map.of( + "logical_availability_zone", "zone-0", + "server_name", "upupaPowerdome", + "availability_zone", "us-east-1e", + "region", "ita-molise-1" + ) + ); + + TaskInfo taskInfo = new TaskInfo(new TaskId("BBB:1481971")); + taskInfo.setType("transport"); + taskInfo.setAction("indices:data/write/reindex"); + taskInfo.setStartTime(1565108484002L); + taskInfo.setRunningTimeNanos(18328639067L); + taskInfo.setStatus( + Map.of( + "time", "now", + "node_count", new ArrayList<>(List.of(1,2,3)), + "node_stats", new ArrayList<>(List.of(new ArrayList<>(List.of(1,2)),new ArrayList<>(List.of(3,4)))) + ) + ); + taskInfo.setCancellable(true); + taskInfo.setHeaders(Map.of()); + + nodeData.setTasks(List.of(taskInfo)); + + ElasticsearchException causer = new ElasticsearchException( + "Elasticsearch exception [type=no_such_node_exception, reason=No such node [AAA]]" + ); + ElasticsearchException caused = new ElasticsearchException( + "Elasticsearch exception [type=failed_node_exception, reason=Failed node [AAA]]", causer + ); + + ElasticsearchException reason = new ElasticsearchException( + "Elasticsearch exception [type=illegal_state_exception, reason=task with id 1186 is already cancelled]" + ); + + TaskOperationFailure tof = new TaskOperationFailure( + "area51node", + 1186L, + "INTERNAL_SERVER_ERROR", + reason + ); + CancelTasksResponse expected = new CancelTasksResponse( + List.of(nodeData), + List.of(tof), + List.of(caused) + ); + + assertEquals(expected, response); + + } +} From dbcf601184c62c1d8665c12423fa4a063d4e003a Mon Sep 17 00:00:00 2001 From: gesino Date: Tue, 12 Nov 2019 19:44:27 +0100 Subject: [PATCH 3/6] fixing tests.... in progress --- .../client/tasks/CancelTasksRequest.java | 3 +- .../elasticsearch/client/tasks/NodeData.java | 8 - .../elasticsearch/client/tasks/TaskInfo.java | 4 + .../TasksClientDocumentationIT.java | 4 +- .../CancelTasksResponseParsingTests.java | 164 +++++++++ .../tasks/CancelTasksResponseTests.java | 329 ++++++++++-------- .../tasks/ElasticSearchExceptionTests.java | 31 ++ 7 files changed, 379 insertions(+), 164 deletions(-) create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java index c1a276bc675ba..98afa8e7015f4 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java @@ -53,9 +53,8 @@ public Optional getTimeout() { return timeout; } - CancelTasksRequest setActions(List actions) { + void setActions(List actions) { this.actions.addAll(actions); - return this; } public List getActions() { diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java index 2bb65db02d916..a87ba3a3923f2 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java @@ -39,14 +39,6 @@ class NodeData { private final Map attributes = new HashMap<>(); private final List tasks = new ArrayList<>(); - /** - * as it is a named object - * in the JSON structure, it requires - * a name in the constructor to cope with signature of: - * {@link ObjectParser#declareNamedObjects(BiConsumer, ObjectParser.NamedObjectParser,ParseField)} - * - * @param nodeId the string identifier of a node - */ NodeData(String nodeId) { this.nodeId = nodeId; } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java index 657795d98dcba..1c2b5faf1575e 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java @@ -134,6 +134,10 @@ void setStatus(Map status) { this.status.putAll(status); } + public Map getStatus() { + return status; + } + void noOpParse(Object s) {} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java index 893f6298f17e7..74ac661fda75b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java @@ -80,7 +80,7 @@ public void testListTasks() throws IOException { request.setParentTaskId(new TaskId("parentTaskId", 42)); // <3> // end::list-tasks-request-filter - // tag::list-tasks-request-detailed~ + // tag::list-tasks-request-detailed request.setDetailed(true); // <1> // end::list-tasks-request-detailed @@ -162,13 +162,11 @@ public void testCancelTasks() throws IOException { // end::cancel-tasks-request // tag::cancel-tasks-request-filter - // request.setTaskId(new org.elasticsearch.client.tasks.TaskId("nodeId1", 42)); //<1> // end::cancel-tasks-request-filter } CancelTasksRequest request = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder().build(); - //request.setTaskId(org.elasticsearch.client.tasks.TaskId.EMPTY_TASK_ID); // tag::cancel-tasks-execute CancelTasksResponse response = client.tasks().cancel(request, RequestOptions.DEFAULT); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java new file mode 100644 index 0000000000000..79f1b517b73d0 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java @@ -0,0 +1,164 @@ +/* + * 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.client.tasks; + +import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CancelTasksResponseParsingTests extends ESTestCase { + + String response = "{\n" + + " \"node_failures\" : [\n" + + " {\n" + + " \"type\" : \"failed_node_exception\",\n" + + " \"reason\" : \"Failed node [AAA]\",\n" + + " \"node_id\" : \"AAA\",\n" + + " \"caused_by\" : {\n" + + " \"type\" : \"no_such_node_exception\",\n" + + " \"reason\" : \"No such node [AAA]\",\n" + + " \"node_id\" : \"AAA\"\n" + + " }\n" + + " }\n" + + " ]," + + " \"task_failures\" : [\n"+ + " {\n"+ + " \"task_id\" : 1186,\n"+ + " \"node_id\" : \"area51node\",\n"+ + " \"status\" : \"INTERNAL_SERVER_ERROR\",\n"+ + " \"reason\" : {\n"+ + " \"type\" : \"illegal_state_exception\",\n"+ + " \"reason\" : \"task with id 1186 is already cancelled\"\n"+ + " }\n"+ + " }\n"+ + " ],\n"+ + " \"nodes\" : {\n" + + " \"BBB\" : {\n" + + " \"name\" : \"instance-0000000004\",\n" + + " \"transport_address\" : \"192.168.1.1:19987\",\n" + + " \"host\" : \"192.168.1.1\",\n" + + " \"ip\" : \"192.168.1.1\",\n" + + " \"roles\" : [\n" + + " \"master\",\n" + + " \"data\",\n" + + " \"ingest\"\n" + + " ],\n" + + " \"attributes\" : {\n" + + " \"logical_availability_zone\" : \"zone-0\",\n" + + " \"server_name\" : \"upupaPowerdome\",\n" + + " \"availability_zone\" : \"us-east-1e\",\n" + + " \"region\" : \"ita-molise-1\" \n" + + " },\n" + + " \"tasks\" : {\n" + + " \"BBB:1481971\" : {\n" + + " \"node\" : \"BBB\",\n" + + " \"id\" : 1481971,\n" + + " \"type\" : \"transport\",\n" + + " \"action\" : \"indices:data/write/reindex\",\n" + + " \"status\" : { \n" + + " \"time\": \"now\",\n"+ + " \"node_count\" : [1,2,3],\n"+ + " \"node_stats\" : [[1,2],[3,4]]\n"+ + " },\n" + + " \"start_time_in_millis\" : 1565108484002,\n" + + " \"running_time_in_nanos\" : 18328639067,\n" + + " \"cancellable\" : true,\n" + + " \"headers\" : { }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + + public void testFromXContent() throws IOException { + + XContentParser parser = JsonXContent.jsonXContent.createParser( + xContentRegistry(), + LoggingDeprecationHandler.INSTANCE, + response); + + CancelTasksResponse response = CancelTasksResponse.fromXContent(parser); + + NodeData nodeData = new NodeData("BBB"); + nodeData.setName("instance-0000000004"); + nodeData.setTransportAddress("192.168.1.1:19987"); + nodeData.setHost("192.168.1.1"); + nodeData.setIp("192.168.1.1"); + nodeData.setRoles(List.of("master", "data", "ingest")); + nodeData.setAttributes( + Map.of( + "logical_availability_zone", "zone-0", + "server_name", "upupaPowerdome", + "availability_zone", "us-east-1e", + "region", "ita-molise-1" + ) + ); + + TaskInfo taskInfo = new TaskInfo(new TaskId("BBB:1481971")); + taskInfo.setType("transport"); + taskInfo.setAction("indices:data/write/reindex"); + taskInfo.setStartTime(1565108484002L); + taskInfo.setRunningTimeNanos(18328639067L); + taskInfo.setStatus( + Map.of( + "time", "now", + "node_count", new ArrayList<>(List.of(1,2,3)), + "node_stats", new ArrayList<>(List.of(new ArrayList<>(List.of(1,2)),new ArrayList<>(List.of(3,4)))) + ) + ); + taskInfo.setCancellable(true); + taskInfo.setHeaders(Map.of()); + + nodeData.setTasks(List.of(taskInfo)); + + ElasticsearchException causer = new ElasticsearchException( + "Elasticsearch exception [type=no_such_node_exception, reason=No such node [AAA]]" + ); + ElasticsearchException caused = new ElasticsearchException( + "Elasticsearch exception [type=failed_node_exception, reason=Failed node [AAA]]", causer + ); + + ElasticsearchException reason = new ElasticsearchException( + "Elasticsearch exception [type=illegal_state_exception, reason=task with id 1186 is already cancelled]" + ); + + TaskOperationFailure tof = new TaskOperationFailure( + "area51node", + 1186L, + "INTERNAL_SERVER_ERROR", + reason + ); + CancelTasksResponse expected = new CancelTasksResponse( + List.of(nodeData), + List.of(tof), + List.of(caused) + ); + + assertEquals(expected, response); + + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java index b363e7e492014..6be7909b2a786 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java @@ -1,164 +1,191 @@ -/* - * 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.client.tasks; -import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.Version; +import org.elasticsearch.action.TaskOperationFailure; +import org.elasticsearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse; +import org.elasticsearch.client.AbstractResponseTestCase; +import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.cluster.node.DiscoveryNodes; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.json.JsonXContent; -import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.tasks.TaskId; +import org.elasticsearch.tasks.TaskInfo; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class CancelTasksResponseTests extends ESTestCase { - - String response = "{\n" + - " \"node_failures\" : [\n" + - " {\n" + - " \"type\" : \"failed_node_exception\",\n" + - " \"reason\" : \"Failed node [AAA]\",\n" + - " \"node_id\" : \"AAA\",\n" + - " \"caused_by\" : {\n" + - " \"type\" : \"no_such_node_exception\",\n" + - " \"reason\" : \"No such node [AAA]\",\n" + - " \"node_id\" : \"AAA\"\n" + - " }\n" + - " }\n" + - " ]," + - " \"task_failures\" : [\n"+ - " {\n"+ - " \"task_id\" : 1186,\n"+ - " \"node_id\" : \"area51node\",\n"+ - " \"status\" : \"INTERNAL_SERVER_ERROR\",\n"+ - " \"reason\" : {\n"+ - " \"type\" : \"illegal_state_exception\",\n"+ - " \"reason\" : \"task with id 1186 is already cancelled\"\n"+ - " }\n"+ - " }\n"+ - " ],\n"+ - " \"nodes\" : {\n" + - " \"BBB\" : {\n" + - " \"name\" : \"instance-0000000004\",\n" + - " \"transport_address\" : \"192.168.1.1:19987\",\n" + - " \"host\" : \"192.168.1.1\",\n" + - " \"ip\" : \"192.168.1.1\",\n" + - " \"roles\" : [\n" + - " \"master\",\n" + - " \"data\",\n" + - " \"ingest\"\n" + - " ],\n" + - " \"attributes\" : {\n" + - " \"logical_availability_zone\" : \"zone-0\",\n" + - " \"server_name\" : \"upupaPowerdome\",\n" + - " \"availability_zone\" : \"us-east-1e\",\n" + - " \"region\" : \"ita-molise-1\" \n" + - " },\n" + - " \"tasks\" : {\n" + - " \"BBB:1481971\" : {\n" + - " \"node\" : \"BBB\",\n" + - " \"id\" : 1481971,\n" + - " \"type\" : \"transport\",\n" + - " \"action\" : \"indices:data/write/reindex\",\n" + - " \"status\" : { \n" + - " \"time\": \"now\",\n"+ - " \"node_count\" : [1,2,3],\n"+ - " \"node_stats\" : [[1,2],[3,4]]\n"+ - " },\n" + - " \"start_time_in_millis\" : 1565108484002,\n" + - " \"running_time_in_nanos\" : 18328639067,\n" + - " \"cancellable\" : true,\n" + - " \"headers\" : { }\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - "}"; - - - public void testFromXContent() throws IOException { - - XContentParser parser = JsonXContent.jsonXContent.createParser( - xContentRegistry(), - LoggingDeprecationHandler.INSTANCE, - response); - - CancelTasksResponse response = CancelTasksResponse.fromXContent(parser); - - NodeData nodeData = new NodeData("BBB"); - nodeData.setName("instance-0000000004"); - nodeData.setTransportAddress("192.168.1.1:19987"); - nodeData.setHost("192.168.1.1"); - nodeData.setIp("192.168.1.1"); - nodeData.setRoles(List.of("master", "data", "ingest")); - nodeData.setAttributes( - Map.of( - "logical_availability_zone", "zone-0", - "server_name", "upupaPowerdome", - "availability_zone", "us-east-1e", - "region", "ita-molise-1" - ) - ); - - TaskInfo taskInfo = new TaskInfo(new TaskId("BBB:1481971")); - taskInfo.setType("transport"); - taskInfo.setAction("indices:data/write/reindex"); - taskInfo.setStartTime(1565108484002L); - taskInfo.setRunningTimeNanos(18328639067L); - taskInfo.setStatus( - Map.of( - "time", "now", - "node_count", new ArrayList<>(List.of(1,2,3)), - "node_stats", new ArrayList<>(List.of(new ArrayList<>(List.of(1,2)),new ArrayList<>(List.of(3,4)))) - ) - ); - taskInfo.setCancellable(true); - taskInfo.setHeaders(Map.of()); - - nodeData.setTasks(List.of(taskInfo)); +import java.net.InetAddress; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; + +public class CancelTasksResponseTests extends AbstractResponseTestCase { + + private static String NODE_ID = "node_id"; + + @Override + protected CancelTasksResponseTests.ByNodeCancelTasksResponse createServerTestInstance(XContentType xContentType) { + List tasks = new ArrayList<>(); + List taskFailures = new ArrayList<>(); + List nodeFailures = new ArrayList<>(); + + for (int i = 0; i < randomIntBetween(1, 4); i++) { + taskFailures.add(new TaskOperationFailure(randomAlphaOfLength(4), (long) i, + new RuntimeException(randomAlphaOfLength(4)))); + } + for (int i = 0; i < randomIntBetween(1, 4); i++) { + nodeFailures.add(new ElasticsearchException(new RuntimeException(randomAlphaOfLength(10)))); + } + + for (int i = 0; i < 4 ; i++) { + tasks.add(new org.elasticsearch.tasks.TaskInfo( + new TaskId(NODE_ID, (long) i), + randomAlphaOfLength(4), + randomAlphaOfLength(4), + randomAlphaOfLength(10), + new FakeTaskStatus(randomAlphaOfLength(4), randomInt()), + randomLongBetween(1, 3), + randomIntBetween(5, 10), + false, + new TaskId("node1", randomLong()), + Map.of("x-header-of", "some-value"))); + } + + return new ByNodeCancelTasksResponse(tasks, taskFailures, nodeFailures); + } - ElasticsearchException causer = new ElasticsearchException( - "Elasticsearch exception [type=no_such_node_exception, reason=No such node [AAA]]" - ); - ElasticsearchException caused = new ElasticsearchException( - "Elasticsearch exception [type=failed_node_exception, reason=Failed node [AAA]]", causer - ); + @Override + protected org.elasticsearch.client.tasks.CancelTasksResponse doParseToClientInstance(XContentParser parser) throws IOException { + return org.elasticsearch.client.tasks.CancelTasksResponse.fromXContent(parser); + } - ElasticsearchException reason = new ElasticsearchException( - "Elasticsearch exception [type=illegal_state_exception, reason=task with id 1186 is already cancelled]" + @Override + protected void assertInstances(ByNodeCancelTasksResponse serverTestInstance, + org.elasticsearch.client.tasks.CancelTasksResponse clientInstance) { + + // checking tasks + List sTasks = serverTestInstance.getTasks(); + List cTasks = clientInstance.getTasks(); + Map cTasksMap = + cTasks.stream().collect(Collectors.toMap(org.elasticsearch.client.tasks.TaskInfo::getTaskId, + Function.identity())); + for(TaskInfo ti: sTasks){ + org.elasticsearch.client.tasks.TaskInfo taskInfo = cTasksMap.get(new org.elasticsearch.client.tasks.TaskId(ti.getTaskId().getNodeId(), ti.getTaskId().getId())); + assertEquals(ti.getAction(),taskInfo.getAction()); + assertEquals(ti.getDescription(),taskInfo.getDescription()); + assertEquals(new HashMap<>(ti.getHeaders()),new HashMap<>(taskInfo.getHeaders())); + assertEquals(ti.getType(),taskInfo.getType()); + assertEquals(ti.getStartTime(),taskInfo.getStartTime()); + assertEquals(ti.getRunningTimeNanos(),taskInfo.getRunningTimeNanos()); + assertEquals(ti.isCancellable(),taskInfo.isCancellable()); + assertEquals(ti.getParentTaskId().getNodeId(),taskInfo.getParentTaskId().getNodeId()); + assertEquals(ti.getParentTaskId().getId(),taskInfo.getParentTaskId().getId()); + FakeTaskStatus status = (FakeTaskStatus) ti.getStatus(); + assertEquals(status.code,taskInfo.getStatus().get("code")); + assertEquals(status.status,taskInfo.getStatus().get("status")); + + } + + //checking failures + List serverNodeFailures = serverTestInstance.getNodeFailures(); + List cNodeFailures = clientInstance.getNodeFailures(); + List sExceptionsMessages = serverNodeFailures.stream().map(x -> + org.elasticsearch.client.tasks.ElasticsearchException.buildMessage("exception", x.getMessage(), null)).collect(Collectors.toList() ); - TaskOperationFailure tof = new TaskOperationFailure( - "area51node", - 1186L, - "INTERNAL_SERVER_ERROR", - reason - ); - CancelTasksResponse expected = new CancelTasksResponse( - List.of(nodeData), - List.of(tof), - List.of(caused) - ); + List cExceptionsMessages = cNodeFailures.stream().map( + org.elasticsearch.client.tasks.ElasticsearchException::getMsg + ).collect(Collectors.toList()); + assertEquals(new HashSet<>(sExceptionsMessages),new HashSet<>(cExceptionsMessages)); + + List sTaskFailures = serverTestInstance.getTaskFailures(); + List cTaskFailures = clientInstance.getTaskFailures(); + + Map cTasksFailuresMap = + cTaskFailures.stream().collect(Collectors.toMap( + org.elasticsearch.client.tasks.TaskOperationFailure::getTaskId, + Function.identity())); + for(TaskOperationFailure tof: sTaskFailures){ + org.elasticsearch.client.tasks.TaskOperationFailure failure = cTasksFailuresMap.get(tof.getTaskId()); + assertEquals(tof.getNodeId(),failure.getNodeId()); + assertTrue(failure.getReason().getMsg().contains("runtime_exception")); + assertTrue(failure.getStatus().contains(""+tof.getStatus().name())); + } + } - assertEquals(expected, response); + public static class FakeTaskStatus implements Task.Status { + + final String status; + final int code; + + public FakeTaskStatus(String status, int code) { + this.status = status; + this.code = code; + } + + @Override + public String getWriteableName() { + return "faker"; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(status); + out.writeInt(code); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("status", status); + builder.field("code", code); + return builder.endObject(); + } + } + /** + * tasks are grouped under nodes, and in order to create DiscoveryNodes we need different + * IP addresses. + * So in this test we assume all tasks are issued by a single node whose name and IP address is hardcoded. + */ + static class ByNodeCancelTasksResponse extends CancelTasksResponse { + + public ByNodeCancelTasksResponse(StreamInput in) throws IOException { + super(in); + } + + public ByNodeCancelTasksResponse( + List tasks, + List taskFailures, + List nodeFailures) { + super(tasks, taskFailures, nodeFailures); + } + + + // it knows the hardcoded address space. + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + + DiscoveryNodes.Builder dnBuilder = new DiscoveryNodes.Builder(); + InetAddress inetAddress = InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, (byte) 0, (byte) 1}); + TransportAddress transportAddress = new TransportAddress(inetAddress, randomIntBetween(0, 65535)); + + dnBuilder.add(new DiscoveryNode(NODE_ID,NODE_ID, transportAddress, emptyMap(), emptySet(), Version.CURRENT)); + + DiscoveryNodes build = dnBuilder.build(); + builder.startObject(); + super.toXContentGroupedByNode(builder, params, build); + builder.endObject(); + return builder; + } } } + + diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java new file mode 100644 index 0000000000000..94479a9087532 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java @@ -0,0 +1,31 @@ +package org.elasticsearch.client.tasks; + +import org.elasticsearch.client.AbstractResponseTestCase; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; + +import java.io.IOException; + +public class ElasticSearchExceptionTests extends AbstractResponseTestCase { + + @Override + protected org.elasticsearch.ElasticsearchException createServerTestInstance(XContentType xContentType) { + IllegalStateException ies = new IllegalStateException("illegal_state"); + IllegalArgumentException iae = new IllegalArgumentException("argument", ies); + org.elasticsearch.ElasticsearchException exception = new org.elasticsearch.ElasticsearchException("elastic_exception", iae); + return exception; + } + + @Override + protected ElasticsearchException doParseToClientInstance(XContentParser parser) throws IOException { + return ElasticsearchException.fromXContent(parser); + } + + @Override + protected void assertInstances(org.elasticsearch.ElasticsearchException serverTestInstance, ElasticsearchException clientInstance) { + + String message = serverTestInstance.getDetailedMessage(); + String msg = clientInstance.getMsg(); + } + +} From 7314ddddf337e9e0559478a9da6f37cd1291e87c Mon Sep 17 00:00:00 2001 From: gesino Date: Wed, 13 Nov 2019 11:13:30 +0100 Subject: [PATCH 4/6] fixing tests done --- .../client/tasks/CancelTasksRequest.java | 3 +- .../client/tasks/CancelTasksResponse.java | 138 ++++-------------- .../client/tasks/ElasticsearchException.java | 6 +- .../client/tasks/ListTasksResponse.java | 138 ++++++++++++++++++ .../elasticsearch/client/tasks/NodeData.java | 1 - .../elasticsearch/client/tasks/TaskInfo.java | 15 +- .../client/TasksRequestConvertersTests.java | 1 - .../tasks/CancelTasksResponseTests.java | 77 ++++++---- .../tasks/ElasticSearchExceptionTests.java | 58 +++++++- 9 files changed, 278 insertions(+), 159 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ListTasksResponse.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java index 98afa8e7015f4..9677c72928195 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksRequest.java @@ -36,9 +36,8 @@ public class CancelTasksRequest implements Validatable { CancelTasksRequest(){} - CancelTasksRequest setNodes(List nodes) { + void setNodes(List nodes) { this.nodes.addAll(nodes); - return this; } public List getNodes() { diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java index d9053f17b9882..200f67da1ee13 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/CancelTasksResponse.java @@ -18,21 +18,13 @@ */ package org.elasticsearch.client.tasks; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - import org.elasticsearch.common.ParseField; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentParser; -import static java.util.stream.Collectors.groupingBy; -import static java.util.stream.Collectors.toList; +import java.io.IOException; +import java.util.List; + import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; /** @@ -41,117 +33,18 @@ * - node failures * - tasks */ -public class CancelTasksResponse { - - private final List taskFailures = new ArrayList<>(); - private final List nodeFailures = new ArrayList<>(); - private final List nodesInfoData = new ArrayList<>(); - private final List tasks = new ArrayList<>(); - private final List taskGroups = new ArrayList<>(); +public class CancelTasksResponse extends ListTasksResponse { CancelTasksResponse(List nodesInfoData, List taskFailures, List nodeFailures) { - if (taskFailures != null) { - this.taskFailures.addAll(taskFailures); - } - if (nodeFailures != null) { - this.nodeFailures.addAll(nodeFailures); - } - if (nodesInfoData != null) { - this.nodesInfoData.addAll(nodesInfoData); - } - this.tasks.addAll(this - .nodesInfoData - .stream() - .flatMap(nodeData -> nodeData.getTasks().stream()) - .collect(toList()) - ); - this.taskGroups.addAll(buildTaskGroups()); - } - - private List buildTaskGroups() { - Map taskGroups = new HashMap<>(); - List topLevelTasks = new ArrayList<>(); - // First populate all tasks - for (TaskInfo taskInfo : this.tasks) { - taskGroups.put(taskInfo.getTaskId(), TaskGroup.builder(taskInfo)); - } - - // Now go through all task group builders and add children to their parents - for (TaskGroup.Builder taskGroup : taskGroups.values()) { - TaskId parentTaskId = taskGroup.getTaskInfo().getParentTaskId(); - if (parentTaskId != null) { - TaskGroup.Builder parentTask = taskGroups.get(parentTaskId); - if (parentTask != null) { - // we found parent in the list of tasks - add it to the parent list - parentTask.addGroup(taskGroup); - } else { - // we got zombie or the parent was filtered out - add it to the top task list - topLevelTasks.add(taskGroup); - } - } else { - // top level task - add it to the top task list - topLevelTasks.add(taskGroup); - } - } - return Collections.unmodifiableList(topLevelTasks.stream().map(TaskGroup.Builder::build).collect(Collectors.toList())); - } - - public List getTasks() { - return tasks; - } - - public Map> getPerNodeTasks() { - return getTasks() - .stream() - .collect(groupingBy(TaskInfo::getNodeId)); - } - - public List getTaskFailures() { - return taskFailures; - } - - public List getNodeFailures() { - return nodeFailures; - } - - public List getTaskGroups() { - return taskGroups; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CancelTasksResponse)) return false; - CancelTasksResponse response = (CancelTasksResponse) o; - return nodesInfoData.equals(response.nodesInfoData) && - Objects.equals(getTaskFailures(), response.getTaskFailures()) && - Objects.equals(getNodeFailures(), response.getNodeFailures()) && - Objects.equals(getTasks(), response.getTasks()) && - Objects.equals(getTaskGroups(), response.getTaskGroups()); - } - - @Override - public int hashCode() { - return Objects.hash(nodesInfoData, getTaskFailures(), getNodeFailures(), getTasks(), getTaskGroups()); + super(nodesInfoData, taskFailures, nodeFailures); } public static CancelTasksResponse fromXContent(final XContentParser parser) throws IOException { return PARSER.parse(parser, null); } - @Override - public String toString() { - return "CancelTasksResponse{" + - "nodesInfoData=" + nodesInfoData + - ", taskFailures=" + taskFailures + - ", nodeFailures=" + nodeFailures + - ", tasks=" + tasks + - ", taskGroups=" + taskGroups + - '}'; - } - private static ConstructingObjectParser PARSER; static { @@ -174,4 +67,25 @@ public String toString() { parser.declareNamedObjects(optionalConstructorArg(), NodeData.PARSER, new ParseField("nodes")); PARSER = parser; } + + @Override + public boolean equals(Object o) { + return super.equals(o); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public String toString() { + return "CancelTasksResponse{" + + "taskFailures=" + taskFailures + + ", nodeFailures=" + nodeFailures + + ", nodesInfoData=" + nodesInfoData + + ", tasks=" + tasks + + ", taskGroups=" + taskGroups + + '}'; + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java index d5e0eb8f64ee2..7893e758c8dc8 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ElasticsearchException.java @@ -70,6 +70,10 @@ public List getSuppressed() { return suppressed; } + void addSuppressed(List suppressed){ + this.suppressed.addAll(suppressed); + } + /** * Generate a {@link ElasticsearchException} from a {@link XContentParser}. This does not * return the original exception type (ie NodeClosedException for example) but just wraps @@ -173,7 +177,7 @@ private static ElasticsearchException innerFromXContent(XContentParser parser, b return e; } - private void addHeader(String key, List value) { + void addHeader(String key, List value) { headers.put(key,value); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ListTasksResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ListTasksResponse.java new file mode 100644 index 0000000000000..722e889d99a5d --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/ListTasksResponse.java @@ -0,0 +1,138 @@ +/* + * 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.client.tasks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; + +public class ListTasksResponse { + + protected final List taskFailures = new ArrayList<>(); + protected final List nodeFailures = new ArrayList<>(); + protected final List nodesInfoData = new ArrayList<>(); + protected final List tasks = new ArrayList<>(); + protected final List taskGroups = new ArrayList<>(); + + ListTasksResponse(List nodesInfoData, + List taskFailures, + List nodeFailures) { + if (taskFailures != null) { + this.taskFailures.addAll(taskFailures); + } + if (nodeFailures != null) { + this.nodeFailures.addAll(nodeFailures); + } + if (nodesInfoData != null) { + this.nodesInfoData.addAll(nodesInfoData); + } + this.tasks.addAll(this + .nodesInfoData + .stream() + .flatMap(nodeData -> nodeData.getTasks().stream()) + .collect(toList()) + ); + this.taskGroups.addAll(buildTaskGroups()); + } + + private List buildTaskGroups() { + Map taskGroups = new HashMap<>(); + List topLevelTasks = new ArrayList<>(); + // First populate all tasks + for (TaskInfo taskInfo : this.tasks) { + taskGroups.put(taskInfo.getTaskId(), TaskGroup.builder(taskInfo)); + } + + // Now go through all task group builders and add children to their parents + for (TaskGroup.Builder taskGroup : taskGroups.values()) { + TaskId parentTaskId = taskGroup.getTaskInfo().getParentTaskId(); + if (parentTaskId != null) { + TaskGroup.Builder parentTask = taskGroups.get(parentTaskId); + if (parentTask != null) { + // we found parent in the list of tasks - add it to the parent list + parentTask.addGroup(taskGroup); + } else { + // we got zombie or the parent was filtered out - add it to the top task list + topLevelTasks.add(taskGroup); + } + } else { + // top level task - add it to the top task list + topLevelTasks.add(taskGroup); + } + } + return topLevelTasks.stream().map(TaskGroup.Builder::build).collect(Collectors.toUnmodifiableList()); + } + + public List getTasks() { + return tasks; + } + + public Map> getPerNodeTasks() { + return getTasks() + .stream() + .collect(groupingBy(TaskInfo::getNodeId)); + } + + public List getTaskFailures() { + return taskFailures; + } + + public List getNodeFailures() { + return nodeFailures; + } + + public List getTaskGroups() { + return taskGroups; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ListTasksResponse)) return false; + ListTasksResponse response = (ListTasksResponse) o; + return nodesInfoData.equals(response.nodesInfoData) && + Objects.equals + (getTaskFailures(), response.getTaskFailures()) && + Objects.equals(getNodeFailures(), response.getNodeFailures()) && + Objects.equals(getTasks(), response.getTasks()) && + Objects.equals(getTaskGroups(), response.getTaskGroups()); + } + + @Override + public int hashCode() { + return Objects.hash(nodesInfoData, getTaskFailures(), getNodeFailures(), getTasks(), getTaskGroups()); + } + + @Override + public String toString() { + return "CancelTasksResponse{" + + "nodesInfoData=" + nodesInfoData + + ", taskFailures=" + taskFailures + + ", nodeFailures=" + nodeFailures + + ", tasks=" + tasks + + ", taskGroups=" + taskGroups + + '}'; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java index a87ba3a3923f2..2a7388e0e595a 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/NodeData.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.function.BiConsumer; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java index 1c2b5faf1575e..c02dc880b9663 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/tasks/TaskInfo.java @@ -25,8 +25,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.function.BiConsumer; - /** * client side counterpart of server side @@ -46,14 +44,6 @@ public class TaskInfo { private final Map status = new HashMap<>(); private final Map headers = new HashMap<>(); - /** - * as it is a named object - * in the JSON structure, it requires - * a name in the constructor to cope with signature of: - * {@link ObjectParser#declareNamedObjects(BiConsumer, ObjectParser.NamedObjectParser, ParseField)} - * - * @param taskId the aggregate identifier of a task (node id + task id ) - */ public TaskInfo(TaskId taskId) { this.taskId = taskId; } @@ -138,10 +128,7 @@ public Map getStatus() { return status; } - void noOpParse(Object s) {} - - - + private void noOpParse(Object s) {} public static final ObjectParser.NamedObjectParser PARSER; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java index 14c1e0085a67c..054cd6a4ea009 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/TasksRequestConvertersTests.java @@ -26,7 +26,6 @@ import org.elasticsearch.test.ESTestCase; import java.util.HashMap; -import java.util.List; import java.util.Map; import static org.hamcrest.CoreMatchers.equalTo; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java index 6be7909b2a786..bdcbbd98e2830 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseTests.java @@ -1,3 +1,21 @@ +/* + * 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.client.tasks; import org.elasticsearch.ElasticsearchException; @@ -19,14 +37,19 @@ import java.io.IOException; import java.net.InetAddress; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; -public class CancelTasksResponseTests extends AbstractResponseTestCase { +public class CancelTasksResponseTests extends AbstractResponseTestCase { private static String NODE_ID = "node_id"; @@ -44,7 +67,7 @@ protected CancelTasksResponseTests.ByNodeCancelTasksResponse createServerTestIns nodeFailures.add(new ElasticsearchException(new RuntimeException(randomAlphaOfLength(10)))); } - for (int i = 0; i < 4 ; i++) { + for (int i = 0; i < 4; i++) { tasks.add(new org.elasticsearch.tasks.TaskInfo( new TaskId(NODE_ID, (long) i), randomAlphaOfLength(4), @@ -76,20 +99,22 @@ protected void assertInstances(ByNodeCancelTasksResponse serverTestInstance, Map cTasksMap = cTasks.stream().collect(Collectors.toMap(org.elasticsearch.client.tasks.TaskInfo::getTaskId, Function.identity())); - for(TaskInfo ti: sTasks){ - org.elasticsearch.client.tasks.TaskInfo taskInfo = cTasksMap.get(new org.elasticsearch.client.tasks.TaskId(ti.getTaskId().getNodeId(), ti.getTaskId().getId())); - assertEquals(ti.getAction(),taskInfo.getAction()); - assertEquals(ti.getDescription(),taskInfo.getDescription()); - assertEquals(new HashMap<>(ti.getHeaders()),new HashMap<>(taskInfo.getHeaders())); - assertEquals(ti.getType(),taskInfo.getType()); - assertEquals(ti.getStartTime(),taskInfo.getStartTime()); - assertEquals(ti.getRunningTimeNanos(),taskInfo.getRunningTimeNanos()); - assertEquals(ti.isCancellable(),taskInfo.isCancellable()); - assertEquals(ti.getParentTaskId().getNodeId(),taskInfo.getParentTaskId().getNodeId()); - assertEquals(ti.getParentTaskId().getId(),taskInfo.getParentTaskId().getId()); + for (TaskInfo ti : sTasks) { + org.elasticsearch.client.tasks.TaskInfo taskInfo = cTasksMap.get( + new org.elasticsearch.client.tasks.TaskId(ti.getTaskId().getNodeId(), ti.getTaskId().getId()) + ); + assertEquals(ti.getAction(), taskInfo.getAction()); + assertEquals(ti.getDescription(), taskInfo.getDescription()); + assertEquals(new HashMap<>(ti.getHeaders()), new HashMap<>(taskInfo.getHeaders())); + assertEquals(ti.getType(), taskInfo.getType()); + assertEquals(ti.getStartTime(), taskInfo.getStartTime()); + assertEquals(ti.getRunningTimeNanos(), taskInfo.getRunningTimeNanos()); + assertEquals(ti.isCancellable(), taskInfo.isCancellable()); + assertEquals(ti.getParentTaskId().getNodeId(), taskInfo.getParentTaskId().getNodeId()); + assertEquals(ti.getParentTaskId().getId(), taskInfo.getParentTaskId().getId()); FakeTaskStatus status = (FakeTaskStatus) ti.getStatus(); - assertEquals(status.code,taskInfo.getStatus().get("code")); - assertEquals(status.status,taskInfo.getStatus().get("status")); + assertEquals(status.code, taskInfo.getStatus().get("code")); + assertEquals(status.status, taskInfo.getStatus().get("status")); } @@ -97,13 +122,15 @@ protected void assertInstances(ByNodeCancelTasksResponse serverTestInstance, List serverNodeFailures = serverTestInstance.getNodeFailures(); List cNodeFailures = clientInstance.getNodeFailures(); List sExceptionsMessages = serverNodeFailures.stream().map(x -> - org.elasticsearch.client.tasks.ElasticsearchException.buildMessage("exception", x.getMessage(), null)).collect(Collectors.toList() + org.elasticsearch.client.tasks.ElasticsearchException.buildMessage( + "exception", x.getMessage(), null) + ).collect(Collectors.toList() ); List cExceptionsMessages = cNodeFailures.stream().map( org.elasticsearch.client.tasks.ElasticsearchException::getMsg ).collect(Collectors.toList()); - assertEquals(new HashSet<>(sExceptionsMessages),new HashSet<>(cExceptionsMessages)); + assertEquals(new HashSet<>(sExceptionsMessages), new HashSet<>(cExceptionsMessages)); List sTaskFailures = serverTestInstance.getTaskFailures(); List cTaskFailures = clientInstance.getTaskFailures(); @@ -112,11 +139,11 @@ protected void assertInstances(ByNodeCancelTasksResponse serverTestInstance, cTaskFailures.stream().collect(Collectors.toMap( org.elasticsearch.client.tasks.TaskOperationFailure::getTaskId, Function.identity())); - for(TaskOperationFailure tof: sTaskFailures){ + for (TaskOperationFailure tof : sTaskFailures) { org.elasticsearch.client.tasks.TaskOperationFailure failure = cTasksFailuresMap.get(tof.getTaskId()); - assertEquals(tof.getNodeId(),failure.getNodeId()); + assertEquals(tof.getNodeId(), failure.getNodeId()); assertTrue(failure.getReason().getMsg().contains("runtime_exception")); - assertTrue(failure.getStatus().contains(""+tof.getStatus().name())); + assertTrue(failure.getStatus().contains("" + tof.getStatus().name())); } } @@ -157,11 +184,11 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws */ static class ByNodeCancelTasksResponse extends CancelTasksResponse { - public ByNodeCancelTasksResponse(StreamInput in) throws IOException { + ByNodeCancelTasksResponse(StreamInput in) throws IOException { super(in); } - public ByNodeCancelTasksResponse( + ByNodeCancelTasksResponse( List tasks, List taskFailures, List nodeFailures) { @@ -174,10 +201,10 @@ public ByNodeCancelTasksResponse( public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { DiscoveryNodes.Builder dnBuilder = new DiscoveryNodes.Builder(); - InetAddress inetAddress = InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, (byte) 0, (byte) 1}); + InetAddress inetAddress = InetAddress.getByAddress(new byte[]{(byte) 192, (byte) 168, (byte) 0, (byte) 1}); TransportAddress transportAddress = new TransportAddress(inetAddress, randomIntBetween(0, 65535)); - dnBuilder.add(new DiscoveryNode(NODE_ID,NODE_ID, transportAddress, emptyMap(), emptySet(), Version.CURRENT)); + dnBuilder.add(new DiscoveryNode(NODE_ID, NODE_ID, transportAddress, emptyMap(), emptySet(), Version.CURRENT)); DiscoveryNodes build = dnBuilder.build(); builder.startObject(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java index 94479a9087532..40d63054a51fa 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java @@ -1,3 +1,21 @@ +/* + * 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.client.tasks; import org.elasticsearch.client.AbstractResponseTestCase; @@ -5,27 +23,61 @@ import org.elasticsearch.common.xcontent.XContentType; import java.io.IOException; +import java.util.List; -public class ElasticSearchExceptionTests extends AbstractResponseTestCase { +public class ElasticSearchExceptionTests extends AbstractResponseTestCase { @Override protected org.elasticsearch.ElasticsearchException createServerTestInstance(XContentType xContentType) { IllegalStateException ies = new IllegalStateException("illegal_state"); IllegalArgumentException iae = new IllegalArgumentException("argument", ies); org.elasticsearch.ElasticsearchException exception = new org.elasticsearch.ElasticsearchException("elastic_exception", iae); + exception.addHeader("key","value"); + exception.addMetadata("es.meta","data"); + exception.addSuppressed(new NumberFormatException("3/0")); return exception; } @Override protected ElasticsearchException doParseToClientInstance(XContentParser parser) throws IOException { + parser.nextToken(); return ElasticsearchException.fromXContent(parser); } @Override protected void assertInstances(org.elasticsearch.ElasticsearchException serverTestInstance, ElasticsearchException clientInstance) { - String message = serverTestInstance.getDetailedMessage(); - String msg = clientInstance.getMsg(); + IllegalArgumentException sCauseLevel1 = (IllegalArgumentException) serverTestInstance.getCause(); + ElasticsearchException cCauseLevel1 = clientInstance.getCause(); + + assertTrue(sCauseLevel1 !=null); + assertTrue(cCauseLevel1 !=null); + + IllegalStateException causeLevel2 = (IllegalStateException) serverTestInstance.getCause().getCause(); + ElasticsearchException cCauseLevel2 = clientInstance.getCause().getCause(); + assertTrue(causeLevel2 !=null); + assertTrue(cCauseLevel2 !=null); + + + ElasticsearchException cause = new ElasticsearchException( + "Elasticsearch exception [type=illegal_state_exception, reason=illegal_state]" + ); + ElasticsearchException caused1 = new ElasticsearchException( + "Elasticsearch exception [type=illegal_argument_exception, reason=argument]",cause + ); + ElasticsearchException caused2 = new ElasticsearchException( + "Elasticsearch exception [type=exception, reason=elastic_exception]",caused1 + ); + + caused2.addHeader("key", List.of("value")); + ElasticsearchException supp = new ElasticsearchException( + "Elasticsearch exception [type=number_format_exception, reason=3/0]" + ); + caused2.addSuppressed(List.of(supp)); + + assertEquals(caused2,clientInstance); + } } From e1e3e84f6b735ce920c47ceb28651f8e8030af6b Mon Sep 17 00:00:00 2001 From: gesino Date: Thu, 14 Nov 2019 19:09:33 +0100 Subject: [PATCH 5/6] fixing comments for tests and doc --- .../TasksClientDocumentationIT.java | 3 + .../CancelTasksResponseParsingTests.java | 164 ------------------ ....java => ElasticsearchExceptionTests.java} | 2 +- 3 files changed, 4 insertions(+), 165 deletions(-) delete mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java rename client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/{ElasticSearchExceptionTests.java => ElasticsearchExceptionTests.java} (98%) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java index 74ac661fda75b..5f2c474925fde 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java @@ -162,6 +162,9 @@ public void testCancelTasks() throws IOException { // end::cancel-tasks-request // tag::cancel-tasks-request-filter + CancelTasksRequest byTaskIdRequest = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder() + .withTaskId(new org.elasticsearch.client.tasks.TaskId("myNode",44L)) + .build(); // end::cancel-tasks-request-filter } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java deleted file mode 100644 index 79f1b517b73d0..0000000000000 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/CancelTasksResponseParsingTests.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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.client.tasks; - -import org.elasticsearch.common.xcontent.LoggingDeprecationHandler; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.json.JsonXContent; -import org.elasticsearch.test.ESTestCase; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class CancelTasksResponseParsingTests extends ESTestCase { - - String response = "{\n" + - " \"node_failures\" : [\n" + - " {\n" + - " \"type\" : \"failed_node_exception\",\n" + - " \"reason\" : \"Failed node [AAA]\",\n" + - " \"node_id\" : \"AAA\",\n" + - " \"caused_by\" : {\n" + - " \"type\" : \"no_such_node_exception\",\n" + - " \"reason\" : \"No such node [AAA]\",\n" + - " \"node_id\" : \"AAA\"\n" + - " }\n" + - " }\n" + - " ]," + - " \"task_failures\" : [\n"+ - " {\n"+ - " \"task_id\" : 1186,\n"+ - " \"node_id\" : \"area51node\",\n"+ - " \"status\" : \"INTERNAL_SERVER_ERROR\",\n"+ - " \"reason\" : {\n"+ - " \"type\" : \"illegal_state_exception\",\n"+ - " \"reason\" : \"task with id 1186 is already cancelled\"\n"+ - " }\n"+ - " }\n"+ - " ],\n"+ - " \"nodes\" : {\n" + - " \"BBB\" : {\n" + - " \"name\" : \"instance-0000000004\",\n" + - " \"transport_address\" : \"192.168.1.1:19987\",\n" + - " \"host\" : \"192.168.1.1\",\n" + - " \"ip\" : \"192.168.1.1\",\n" + - " \"roles\" : [\n" + - " \"master\",\n" + - " \"data\",\n" + - " \"ingest\"\n" + - " ],\n" + - " \"attributes\" : {\n" + - " \"logical_availability_zone\" : \"zone-0\",\n" + - " \"server_name\" : \"upupaPowerdome\",\n" + - " \"availability_zone\" : \"us-east-1e\",\n" + - " \"region\" : \"ita-molise-1\" \n" + - " },\n" + - " \"tasks\" : {\n" + - " \"BBB:1481971\" : {\n" + - " \"node\" : \"BBB\",\n" + - " \"id\" : 1481971,\n" + - " \"type\" : \"transport\",\n" + - " \"action\" : \"indices:data/write/reindex\",\n" + - " \"status\" : { \n" + - " \"time\": \"now\",\n"+ - " \"node_count\" : [1,2,3],\n"+ - " \"node_stats\" : [[1,2],[3,4]]\n"+ - " },\n" + - " \"start_time_in_millis\" : 1565108484002,\n" + - " \"running_time_in_nanos\" : 18328639067,\n" + - " \"cancellable\" : true,\n" + - " \"headers\" : { }\n" + - " }\n" + - " }\n" + - " }\n" + - " }\n" + - "}"; - - - public void testFromXContent() throws IOException { - - XContentParser parser = JsonXContent.jsonXContent.createParser( - xContentRegistry(), - LoggingDeprecationHandler.INSTANCE, - response); - - CancelTasksResponse response = CancelTasksResponse.fromXContent(parser); - - NodeData nodeData = new NodeData("BBB"); - nodeData.setName("instance-0000000004"); - nodeData.setTransportAddress("192.168.1.1:19987"); - nodeData.setHost("192.168.1.1"); - nodeData.setIp("192.168.1.1"); - nodeData.setRoles(List.of("master", "data", "ingest")); - nodeData.setAttributes( - Map.of( - "logical_availability_zone", "zone-0", - "server_name", "upupaPowerdome", - "availability_zone", "us-east-1e", - "region", "ita-molise-1" - ) - ); - - TaskInfo taskInfo = new TaskInfo(new TaskId("BBB:1481971")); - taskInfo.setType("transport"); - taskInfo.setAction("indices:data/write/reindex"); - taskInfo.setStartTime(1565108484002L); - taskInfo.setRunningTimeNanos(18328639067L); - taskInfo.setStatus( - Map.of( - "time", "now", - "node_count", new ArrayList<>(List.of(1,2,3)), - "node_stats", new ArrayList<>(List.of(new ArrayList<>(List.of(1,2)),new ArrayList<>(List.of(3,4)))) - ) - ); - taskInfo.setCancellable(true); - taskInfo.setHeaders(Map.of()); - - nodeData.setTasks(List.of(taskInfo)); - - ElasticsearchException causer = new ElasticsearchException( - "Elasticsearch exception [type=no_such_node_exception, reason=No such node [AAA]]" - ); - ElasticsearchException caused = new ElasticsearchException( - "Elasticsearch exception [type=failed_node_exception, reason=Failed node [AAA]]", causer - ); - - ElasticsearchException reason = new ElasticsearchException( - "Elasticsearch exception [type=illegal_state_exception, reason=task with id 1186 is already cancelled]" - ); - - TaskOperationFailure tof = new TaskOperationFailure( - "area51node", - 1186L, - "INTERNAL_SERVER_ERROR", - reason - ); - CancelTasksResponse expected = new CancelTasksResponse( - List.of(nodeData), - List.of(tof), - List.of(caused) - ); - - assertEquals(expected, response); - - } -} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticsearchExceptionTests.java similarity index 98% rename from client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java rename to client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticsearchExceptionTests.java index 40d63054a51fa..371f72fa660bd 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticSearchExceptionTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/tasks/ElasticsearchExceptionTests.java @@ -25,7 +25,7 @@ import java.io.IOException; import java.util.List; -public class ElasticSearchExceptionTests extends AbstractResponseTestCase { @Override From c3ae79099ad41e8af697ec7f83b742c07f147a45 Mon Sep 17 00:00:00 2001 From: gesino Date: Thu, 14 Nov 2019 19:26:14 +0100 Subject: [PATCH 6/6] fixing doc generation --- .../client/documentation/TasksClientDocumentationIT.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java index 5f2c474925fde..d0bcb418e3659 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/TasksClientDocumentationIT.java @@ -162,9 +162,9 @@ public void testCancelTasks() throws IOException { // end::cancel-tasks-request // tag::cancel-tasks-request-filter - CancelTasksRequest byTaskIdRequest = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder() - .withTaskId(new org.elasticsearch.client.tasks.TaskId("myNode",44L)) - .build(); + CancelTasksRequest byTaskIdRequest = new org.elasticsearch.client.tasks.CancelTasksRequest.Builder() // <1> + .withTaskId(new org.elasticsearch.client.tasks.TaskId("myNode",44L)) // <2> + .build(); // <3> // end::cancel-tasks-request-filter }