Skip to content

Commit ca09936

Browse files
authored
HLRC: Get Deprecation Info API (#36279)
This commit adds the Get Deprecation Info API and associated documentation. Relates #29827
1 parent c32e4fb commit ca09936

File tree

10 files changed

+547
-2
lines changed

10 files changed

+547
-2
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/MigrationClient.java

+26
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
package org.elasticsearch.client;
2121

22+
import org.elasticsearch.client.migration.DeprecationInfoRequest;
23+
import org.elasticsearch.client.migration.DeprecationInfoResponse;
2224
import org.elasticsearch.client.migration.IndexUpgradeInfoRequest;
2325
import org.elasticsearch.client.migration.IndexUpgradeInfoResponse;
2426
import org.elasticsearch.action.ActionListener;
@@ -72,4 +74,28 @@ public void upgradeAsync(IndexUpgradeRequest request, RequestOptions options, Ac
7274
restHighLevelClient.performRequestAsyncAndParseEntity(request, MigrationRequestConverters::migrate, options,
7375
BulkByScrollResponse::fromXContent, listener, Collections.emptySet());
7476
}
77+
78+
/**
79+
* Get deprecation info for one or more indices
80+
* @param request the request
81+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
82+
* @return the response
83+
* @throws IOException in case there is a problem sending the request or parsing back the response
84+
*/
85+
public DeprecationInfoResponse getDeprecationInfo(DeprecationInfoRequest request, RequestOptions options) throws IOException {
86+
return restHighLevelClient.performRequestAndParseEntity(request, MigrationRequestConverters::getDeprecationInfo, options,
87+
DeprecationInfoResponse::fromXContent, Collections.emptySet());
88+
}
89+
90+
/**
91+
* Asynchronously get deprecation info for one or more indices
92+
* @param request the request
93+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
94+
* @param listener the listener to be notified upon request completion
95+
*/
96+
public void getDeprecationInfoAsync(DeprecationInfoRequest request, RequestOptions options,
97+
ActionListener<DeprecationInfoResponse> listener) {
98+
restHighLevelClient.performRequestAsyncAndParseEntity(request, MigrationRequestConverters::getDeprecationInfo, options,
99+
DeprecationInfoResponse::fromXContent, listener, Collections.emptySet());
100+
}
75101
}

client/rest-high-level/src/main/java/org/elasticsearch/client/MigrationRequestConverters.java

+10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.apache.http.client.methods.HttpGet;
2323
import org.apache.http.client.methods.HttpPost;
24+
import org.elasticsearch.client.migration.DeprecationInfoRequest;
2425
import org.elasticsearch.client.migration.IndexUpgradeInfoRequest;
2526
import org.elasticsearch.client.migration.IndexUpgradeRequest;
2627

@@ -48,6 +49,15 @@ static Request submitMigrateTask(IndexUpgradeRequest indexUpgradeRequest) {
4849
return prepareMigrateRequest(indexUpgradeRequest, false);
4950
}
5051

52+
static Request getDeprecationInfo(DeprecationInfoRequest deprecationInfoRequest) {
53+
String endpoint = new RequestConverters.EndpointBuilder()
54+
.addCommaSeparatedPathParts(deprecationInfoRequest.getIndices())
55+
.addPathPartAsIs("_migration", "deprecations")
56+
.build();
57+
58+
return new Request(HttpGet.METHOD_NAME, endpoint);
59+
}
60+
5161
private static Request prepareMigrateRequest(IndexUpgradeRequest indexUpgradeRequest, boolean waitForCompletion) {
5262
String endpoint = new RequestConverters.EndpointBuilder()
5363
.addPathPartAsIs("_migration", "upgrade")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.migration;
21+
22+
import org.elasticsearch.client.Validatable;
23+
24+
import java.util.Collections;
25+
import java.util.List;
26+
import java.util.Objects;
27+
28+
public class DeprecationInfoRequest implements Validatable {
29+
30+
private final List<String> indices;
31+
32+
public DeprecationInfoRequest(List<String> indices) {
33+
this.indices = Collections.unmodifiableList(Objects.requireNonNull(indices, "indices cannot be null"));
34+
}
35+
36+
public DeprecationInfoRequest() {
37+
this.indices = Collections.unmodifiableList(Collections.emptyList());
38+
}
39+
40+
public List<String> getIndices() {
41+
return indices;
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.migration;
21+
22+
import org.elasticsearch.common.Nullable;
23+
import org.elasticsearch.common.ParseField;
24+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
25+
import org.elasticsearch.common.xcontent.XContentParser;
26+
27+
import java.io.IOException;
28+
import java.util.ArrayList;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Locale;
32+
import java.util.Map;
33+
import java.util.Objects;
34+
35+
public class DeprecationInfoResponse {
36+
37+
private static final ParseField CLUSTER_SETTINGS = new ParseField("cluster_settings");
38+
private static final ParseField NODE_SETTINGS = new ParseField("node_settings");
39+
private static final ParseField INDEX_SETTINGS = new ParseField("index_settings");
40+
41+
private final List<DeprecationIssue> clusterSettingsIssues;
42+
private final List<DeprecationIssue> nodeSettingsIssues;
43+
private final Map<String, List<DeprecationIssue>> indexSettingsIssues;
44+
45+
public DeprecationInfoResponse(List<DeprecationIssue> clusterSettingsIssues, List<DeprecationIssue> nodeSettingsIssues,
46+
Map<String, List<DeprecationIssue>> indexSettingsIssues) {
47+
this.clusterSettingsIssues = Objects.requireNonNull(clusterSettingsIssues, "cluster settings issues cannot be null");
48+
this.nodeSettingsIssues = Objects.requireNonNull(nodeSettingsIssues, "node settings issues cannot be null");
49+
this.indexSettingsIssues = Objects.requireNonNull(indexSettingsIssues, "index settings issues cannot be null");
50+
}
51+
52+
public List<DeprecationIssue> getClusterSettingsIssues() {
53+
return clusterSettingsIssues;
54+
}
55+
56+
public List<DeprecationIssue> getNodeSettingsIssues() {
57+
return nodeSettingsIssues;
58+
}
59+
60+
public Map<String, List<DeprecationIssue>> getIndexSettingsIssues() {
61+
return indexSettingsIssues;
62+
}
63+
64+
private static List<DeprecationIssue> parseDeprecationIssues(XContentParser parser) throws IOException {
65+
List<DeprecationIssue> issues = new ArrayList<>();
66+
XContentParser.Token token = null;
67+
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
68+
if (token == XContentParser.Token.START_OBJECT) {
69+
issues.add(DeprecationIssue.PARSER.parse(parser, null));
70+
}
71+
}
72+
return issues;
73+
}
74+
75+
public static DeprecationInfoResponse fromXContent(XContentParser parser) throws IOException {
76+
Map<String, List<DeprecationIssue>> indexSettings = new HashMap<>();
77+
List<DeprecationIssue> clusterSettings = new ArrayList<>();
78+
List<DeprecationIssue> nodeSettings = new ArrayList<>();
79+
String fieldName = null;
80+
XContentParser.Token token;
81+
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
82+
if (token == XContentParser.Token.FIELD_NAME) {
83+
fieldName = parser.currentName();
84+
} else if (CLUSTER_SETTINGS.getPreferredName().equals(fieldName)) {
85+
clusterSettings.addAll(parseDeprecationIssues(parser));
86+
} else if (NODE_SETTINGS.getPreferredName().equals(fieldName)) {
87+
nodeSettings.addAll(parseDeprecationIssues(parser));
88+
} else if (INDEX_SETTINGS.getPreferredName().equals(fieldName)) {
89+
// parse out the key/value pairs
90+
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
91+
String key = parser.currentName();
92+
List<DeprecationIssue> value = parseDeprecationIssues(parser);
93+
if (value.size() > 0) { // only add indices that contain deprecation issues
94+
indexSettings.put(key, value);
95+
}
96+
}
97+
}
98+
}
99+
return new DeprecationInfoResponse(clusterSettings, nodeSettings, indexSettings);
100+
}
101+
102+
@Override
103+
public boolean equals(Object o) {
104+
if (this == o) return true;
105+
if (o == null || getClass() != o.getClass()) return false;
106+
DeprecationInfoResponse that = (DeprecationInfoResponse) o;
107+
return Objects.equals(clusterSettingsIssues, that.clusterSettingsIssues) &&
108+
Objects.equals(nodeSettingsIssues, that.nodeSettingsIssues) &&
109+
Objects.equals(indexSettingsIssues, that.indexSettingsIssues);
110+
}
111+
112+
@Override
113+
public int hashCode() {
114+
return Objects.hash(clusterSettingsIssues, nodeSettingsIssues, indexSettingsIssues);
115+
}
116+
117+
@Override
118+
public String toString() {
119+
return clusterSettingsIssues.toString() + ":" + nodeSettingsIssues.toString() + ":" + indexSettingsIssues.toString();
120+
}
121+
122+
/**
123+
* Information about deprecated items
124+
*/
125+
public static class DeprecationIssue {
126+
127+
private static final ParseField LEVEL = new ParseField("level");
128+
private static final ParseField MESSAGE = new ParseField("message");
129+
private static final ParseField URL = new ParseField("url");
130+
private static final ParseField DETAILS = new ParseField("details");
131+
132+
static final ConstructingObjectParser<DeprecationIssue, Void> PARSER =
133+
new ConstructingObjectParser<>("deprecation_issue", true,
134+
a -> new DeprecationIssue(Level.fromString((String) a[0]), (String) a[1], (String) a[2], (String) a[3]));
135+
136+
static {
137+
PARSER.declareString(ConstructingObjectParser.constructorArg(), LEVEL);
138+
PARSER.declareString(ConstructingObjectParser.constructorArg(), MESSAGE);
139+
PARSER.declareString(ConstructingObjectParser.constructorArg(), URL);
140+
PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), DETAILS);
141+
}
142+
143+
public enum Level {
144+
NONE,
145+
INFO,
146+
WARNING,
147+
CRITICAL
148+
;
149+
150+
public static Level fromString(String value) {
151+
return Level.valueOf(value.toUpperCase(Locale.ROOT));
152+
}
153+
154+
@Override
155+
public String toString() {
156+
return name().toLowerCase(Locale.ROOT);
157+
}
158+
}
159+
160+
private Level level;
161+
private String message;
162+
private String url;
163+
private String details;
164+
165+
public DeprecationIssue(Level level, String message, String url, @Nullable String details) {
166+
this.level = level;
167+
this.message = message;
168+
this.url = url;
169+
this.details = details;
170+
}
171+
172+
public Level getLevel() {
173+
return level;
174+
}
175+
176+
public String getMessage() {
177+
return message;
178+
}
179+
180+
public String getUrl() {
181+
return url;
182+
}
183+
184+
public String getDetails() {
185+
return details;
186+
}
187+
188+
@Override
189+
public boolean equals(Object o) {
190+
if (this == o) {
191+
return true;
192+
}
193+
if (o == null || getClass() != o.getClass()) {
194+
return false;
195+
}
196+
DeprecationIssue that = (DeprecationIssue) o;
197+
return Objects.equals(level, that.level) &&
198+
Objects.equals(message, that.message) &&
199+
Objects.equals(url, that.url) &&
200+
Objects.equals(details, that.details);
201+
}
202+
203+
@Override
204+
public int hashCode() {
205+
return Objects.hash(level, message, url, details);
206+
}
207+
}
208+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/MigrationIT.java

+14
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,20 @@
2020
package org.elasticsearch.client;
2121

2222
import org.elasticsearch.ElasticsearchStatusException;
23+
import org.elasticsearch.client.migration.DeprecationInfoRequest;
24+
import org.elasticsearch.client.migration.DeprecationInfoResponse;
2325
import org.elasticsearch.client.migration.IndexUpgradeInfoRequest;
2426
import org.elasticsearch.client.migration.IndexUpgradeInfoResponse;
2527
import org.elasticsearch.client.migration.IndexUpgradeRequest;
2628
import org.elasticsearch.client.tasks.TaskSubmissionResponse;
2729
import org.elasticsearch.common.settings.Settings;
2830

2931
import java.io.IOException;
32+
import java.util.Collections;
3033
import java.util.function.BooleanSupplier;
3134

3235
import static org.hamcrest.Matchers.containsString;
36+
import static org.hamcrest.Matchers.equalTo;
3337

3438
public class MigrationIT extends ESRestHighLevelClientTestCase {
3539

@@ -73,6 +77,16 @@ public void testUpgradeWithTaskApi() throws IOException, InterruptedException {
7377
awaitBusy(hasUpgradeCompleted);
7478
}
7579

80+
public void testGetDeprecationInfo() throws IOException {
81+
createIndex("test", Settings.EMPTY);
82+
DeprecationInfoRequest request = new DeprecationInfoRequest(Collections.singletonList("test"));
83+
DeprecationInfoResponse response = highLevelClient().migration().getDeprecationInfo(request, RequestOptions.DEFAULT);
84+
// a test like this cannot test actual deprecations
85+
assertThat(response.getClusterSettingsIssues().size(), equalTo(0));
86+
assertThat(response.getIndexSettingsIssues().size(), equalTo(0));
87+
assertThat(response.getNodeSettingsIssues().size(), equalTo(0));
88+
}
89+
7690
/**
7791
* Using low-level api as high-level-rest-client's getTaskById work is in progress.
7892
* TODO revisit once that work is finished

0 commit comments

Comments
 (0)