Skip to content

Commit e28aa3e

Browse files
authored
[Transform] Fix Missing Config Errors (#134963) (#135387)
When there are more Transforms than the current page size, GET _transform will mistakenly display an error message `Found task for transform [...], but no configuration for it. To delete this transform use DELETE with force=true.`. When the page size is smaller than the reported total count of transforms, we will now get all Transform Ids and compare that to the running transforms to generate the dangling tasks error message. Resolve #134263
1 parent 84835b2 commit e28aa3e

File tree

14 files changed

+334
-72
lines changed

14 files changed

+334
-72
lines changed

docs/changelog/134963.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 134963
2+
summary: Fix a bug in the GET _transform API that incorrectly claims some Transform configurations are missing
3+
area: Transform
4+
type: bug
5+
issues:
6+
- 134263
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9170000,9112009,9000018,8841070,8840011
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
initial_elasticsearch_8_18_8,8840010
1+
transform_check_for_dangling_tasks,8840011
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
initial_elasticsearch_8_19_5,8841069
1+
transform_check_for_dangling_tasks,8841070
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
transform_check_for_dangling_tasks,9000018
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
esql_fixed_index_like,9112002
1+
transform_check_for_dangling_tasks,9112009
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
esql_fixed_index_like,9119000
1+
transform_check_for_dangling_tasks,9170000

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/TransformField.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public final class TransformField {
5959
public static final ParseField MAX_AGE = new ParseField("max_age");
6060

6161
public static final ParseField ALLOW_NO_MATCH = new ParseField("allow_no_match");
62+
public static final ParseField CHECK_FOR_DANGLING_TASKS = new ParseField("check_dangling_tasks");
6263
/**
6364
* Fields for checkpointing
6465
*/

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/transform/action/GetTransformAction.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package org.elasticsearch.xpack.core.transform.action;
99

10+
import org.elasticsearch.TransportVersion;
1011
import org.elasticsearch.TransportVersions;
1112
import org.elasticsearch.action.ActionRequestValidationException;
1213
import org.elasticsearch.action.ActionType;
@@ -16,6 +17,7 @@
1617
import org.elasticsearch.common.io.stream.Writeable;
1718
import org.elasticsearch.common.logging.DeprecationCategory;
1819
import org.elasticsearch.common.logging.DeprecationLogger;
20+
import org.elasticsearch.core.TimeValue;
1921
import org.elasticsearch.xcontent.ParseField;
2022
import org.elasticsearch.xcontent.ToXContentObject;
2123
import org.elasticsearch.xcontent.XContentBuilder;
@@ -39,6 +41,8 @@ public class GetTransformAction extends ActionType<GetTransformAction.Response>
3941
public static final GetTransformAction INSTANCE = new GetTransformAction();
4042
public static final String NAME = "cluster:monitor/transform/get";
4143

44+
static final TransportVersion DANGLING_TASKS = TransportVersion.fromName("transform_check_for_dangling_tasks");
45+
4246
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(GetTransformAction.class);
4347

4448
private GetTransformAction() {
@@ -47,24 +51,49 @@ private GetTransformAction() {
4751

4852
public static class Request extends AbstractGetResourcesRequest {
4953

54+
// for legacy purposes, this transport action previously had no timeout
55+
private static final TimeValue LEGACY_TIMEOUT_VALUE = TimeValue.MAX_VALUE;
5056
private static final int MAX_SIZE_RETURN = 1000;
57+
private final boolean checkForDanglingTasks;
58+
private final TimeValue timeout;
5159

5260
public Request(String id) {
53-
super(id, PageParams.defaultParams(), true);
61+
this(id, false, LEGACY_TIMEOUT_VALUE);
5462
}
5563

56-
public Request() {
57-
super(null, PageParams.defaultParams(), true);
64+
public Request(String id, boolean checkForDanglingTasks, TimeValue timeout) {
65+
super(id, PageParams.defaultParams(), true);
66+
this.checkForDanglingTasks = checkForDanglingTasks;
67+
this.timeout = timeout;
5868
}
5969

6070
public Request(StreamInput in) throws IOException {
6171
super(in);
72+
this.checkForDanglingTasks = in.getTransportVersion().onOrAfter(DANGLING_TASKS) ? in.readBoolean() : true;
73+
this.timeout = in.getTransportVersion().onOrAfter(DANGLING_TASKS) ? in.readTimeValue() : LEGACY_TIMEOUT_VALUE;
74+
}
75+
76+
@Override
77+
public void writeTo(StreamOutput out) throws IOException {
78+
super.writeTo(out);
79+
if (out.getTransportVersion().onOrAfter(DANGLING_TASKS)) {
80+
out.writeBoolean(checkForDanglingTasks);
81+
out.writeTimeValue(timeout);
82+
}
6283
}
6384

6485
public String getId() {
6586
return getResourceId();
6687
}
6788

89+
public boolean checkForDanglingTasks() {
90+
return checkForDanglingTasks;
91+
}
92+
93+
public TimeValue timeout() {
94+
return timeout;
95+
}
96+
6897
@Override
6998
public ActionRequestValidationException validate() {
7099
ActionRequestValidationException exception = null;
@@ -86,6 +115,20 @@ public String getCancelableTaskDescription() {
86115
public String getResourceIdField() {
87116
return TransformField.ID.getPreferredName();
88117
}
118+
119+
@Override
120+
public boolean equals(Object obj) {
121+
return this == obj
122+
|| (obj instanceof Request other
123+
&& super.equals(obj)
124+
&& (checkForDanglingTasks == other.checkForDanglingTasks)
125+
&& Objects.equals(timeout, other.timeout));
126+
}
127+
128+
@Override
129+
public int hashCode() {
130+
return Objects.hash(super.hashCode(), checkForDanglingTasks, timeout);
131+
}
89132
}
90133

91134
public static class Response extends AbstractGetResourcesResponse<TransformConfig> implements ToXContentObject {

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/action/GetTransformActionRequestTests.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,37 @@
77

88
package org.elasticsearch.xpack.core.transform.action;
99

10+
import org.elasticsearch.TransportVersion;
1011
import org.elasticsearch.cluster.metadata.Metadata;
1112
import org.elasticsearch.common.io.stream.Writeable;
12-
import org.elasticsearch.test.AbstractWireSerializingTestCase;
13+
import org.elasticsearch.core.TimeValue;
14+
import org.elasticsearch.xpack.core.ml.AbstractBWCWireSerializationTestCase;
1315
import org.elasticsearch.xpack.core.transform.action.GetTransformAction.Request;
1416

15-
public class GetTransformActionRequestTests extends AbstractWireSerializingTestCase<Request> {
17+
import static org.elasticsearch.xpack.core.transform.action.GetTransformAction.DANGLING_TASKS;
18+
19+
public class GetTransformActionRequestTests extends AbstractBWCWireSerializationTestCase<Request> {
1620

1721
@Override
1822
protected Request createTestInstance() {
1923
if (randomBoolean()) {
2024
return new Request(Metadata.ALL);
2125
}
22-
return new Request(randomAlphaOfLengthBetween(1, 20));
26+
return new Request(randomAlphaOfLengthBetween(1, 20), randomBoolean(), randomPositiveTimeValue());
2327
}
2428

2529
@Override
2630
protected Request mutateInstance(Request instance) {
27-
return null;// TODO implement https://github.com/elastic/elasticsearch/issues/25929
31+
return randomValueOtherThan(instance, this::createTestInstance);
2832
}
2933

3034
@Override
3135
protected Writeable.Reader<Request> instanceReader() {
3236
return Request::new;
3337
}
38+
39+
@Override
40+
protected Request mutateInstanceForVersion(Request instance, TransportVersion version) {
41+
return version.onOrAfter(DANGLING_TASKS) ? instance : new Request(instance.getId(), true, TimeValue.MAX_VALUE);
42+
}
3443
}

0 commit comments

Comments
 (0)