Skip to content

Commit 2657496

Browse files
authored
Change Get Snapshottable Features endpoint to _features (#69755)
The endpoint `_snapshottable_features` is long and implies incorrect things about this API - it is used not just for snapshots, but also for the upcoming reset API. Following discussions on the team, this commit changes the endpoint to `_features` and removes the connection between this API and snapshots, as snapshots are not the only use for the output of this API.
1 parent be3fdd2 commit 2657496

File tree

20 files changed

+184
-100
lines changed

20 files changed

+184
-100
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.client;
10+
11+
import org.elasticsearch.action.ActionListener;
12+
import org.elasticsearch.client.snapshots.GetFeaturesRequest;
13+
import org.elasticsearch.client.snapshots.GetFeaturesResponse;
14+
15+
import java.io.IOException;
16+
17+
import static java.util.Collections.emptySet;
18+
19+
/**
20+
* A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Snapshot API.
21+
* <p>
22+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/features-apis.html">Snapshot API on elastic.co</a>
23+
*/
24+
public class FeaturesClient {
25+
private final RestHighLevelClient restHighLevelClient;
26+
27+
FeaturesClient(RestHighLevelClient restHighLevelClient) {
28+
this.restHighLevelClient = restHighLevelClient;
29+
}
30+
31+
/**
32+
* Get a list of features which can be included in a snapshot as feature states.
33+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/get-features-api.html"> Get Snapshottable
34+
* Features API on elastic.co</a>
35+
*
36+
* @param getFeaturesRequest the request
37+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
38+
* @return the response
39+
* @throws IOException in case there is a problem sending the request or parsing back the response
40+
*/
41+
public GetFeaturesResponse getFeatures(GetFeaturesRequest getFeaturesRequest, RequestOptions options)
42+
throws IOException {
43+
return restHighLevelClient.performRequestAndParseEntity(
44+
getFeaturesRequest,
45+
FeaturesRequestConverters::getFeatures,
46+
options,
47+
GetFeaturesResponse::parse,
48+
emptySet()
49+
);
50+
}
51+
52+
/**
53+
* Asynchronously get a list of features which can be included in a snapshot as feature states.
54+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/get-features-api.html"> Get Snapshottable
55+
* Features API on elastic.co</a>
56+
*
57+
* @param getFeaturesRequest the request
58+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
59+
* @param listener the listener to be notified upon request completion
60+
* @return cancellable that may be used to cancel the request
61+
*/
62+
public Cancellable getFeaturesAsync(
63+
GetFeaturesRequest getFeaturesRequest, RequestOptions options,
64+
ActionListener<GetFeaturesResponse> listener) {
65+
return restHighLevelClient.performRequestAsyncAndParseEntity(
66+
getFeaturesRequest,
67+
FeaturesRequestConverters::getFeatures,
68+
options,
69+
GetFeaturesResponse::parse,
70+
listener,
71+
emptySet()
72+
);
73+
}
74+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.client;
10+
11+
import org.apache.http.client.methods.HttpGet;
12+
import org.elasticsearch.client.snapshots.GetFeaturesRequest;
13+
14+
public class FeaturesRequestConverters {
15+
16+
private FeaturesRequestConverters() {}
17+
18+
static Request getFeatures(GetFeaturesRequest getFeaturesRequest) {
19+
String endpoint = "/_features";
20+
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
21+
RequestConverters.Params parameters = new RequestConverters.Params();
22+
parameters.withMasterTimeout(getFeaturesRequest.masterNodeTimeout());
23+
request.addParameters(parameters.asMap());
24+
return request;
25+
}
26+
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ public class RestHighLevelClient implements Closeable {
265265
private final AsyncSearchClient asyncSearchClient = new AsyncSearchClient(this);
266266
private final TextStructureClient textStructureClient = new TextStructureClient(this);
267267
private final SearchableSnapshotsClient searchableSnapshotsClient = new SearchableSnapshotsClient(this);
268+
private final FeaturesClient featuresClient = new FeaturesClient(this);
268269

269270
/**
270271
* Creates a {@link RestHighLevelClient} given the low level {@link RestClientBuilder} that allows to build the
@@ -465,6 +466,16 @@ public SearchableSnapshotsClient searchableSnapshots() {
465466
return searchableSnapshotsClient;
466467
}
467468

469+
/**
470+
* A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Searchable Snapshots APIs.
471+
* <p>
472+
* See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/searchable-snapshots-apis.html">Searchable Snapshots
473+
* APIs on elastic.co</a> for more information.
474+
*/
475+
public FeaturesClient features() {
476+
return featuresClient;
477+
}
478+
468479
/**
469480
* Provides methods for accessing the Elastic Licensed Migration APIs that
470481
* are shipped with the default distribution of Elasticsearch. All of

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

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
2929
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
3030
import org.elasticsearch.action.support.master.AcknowledgedResponse;
31-
import org.elasticsearch.client.snapshots.GetSnapshottableFeaturesRequest;
32-
import org.elasticsearch.client.snapshots.GetSnapshottableFeaturesResponse;
3331

3432
import java.io.IOException;
3533

@@ -380,47 +378,4 @@ public Cancellable deleteAsync(DeleteSnapshotRequest deleteSnapshotRequest, Requ
380378
SnapshotRequestConverters::deleteSnapshot, options,
381379
AcknowledgedResponse::fromXContent, listener, emptySet());
382380
}
383-
384-
/**
385-
* Get a list of features which can be included in a snapshot as feature states.
386-
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/get-snapshottable-features-api.html"> Get Snapshottable
387-
* Features API on elastic.co</a>
388-
*
389-
* @param getFeaturesRequest the request
390-
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
391-
* @return the response
392-
* @throws IOException in case there is a problem sending the request or parsing back the response
393-
*/
394-
public GetSnapshottableFeaturesResponse getFeatures(GetSnapshottableFeaturesRequest getFeaturesRequest, RequestOptions options)
395-
throws IOException {
396-
return restHighLevelClient.performRequestAndParseEntity(
397-
getFeaturesRequest,
398-
SnapshotRequestConverters::getSnapshottableFeatures,
399-
options,
400-
GetSnapshottableFeaturesResponse::parse,
401-
emptySet()
402-
);
403-
}
404-
405-
/**
406-
* Asynchronously get a list of features which can be included in a snapshot as feature states.
407-
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/get-snapshottable-features-api.html"> Get Snapshottable
408-
* Features API on elastic.co</a>
409-
*
410-
* @param getFeaturesRequest the request
411-
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
412-
* @param listener the listener to be notified upon request completion
413-
* @return cancellable that may be used to cancel the request
414-
*/
415-
public Cancellable getFeaturesAsync(GetSnapshottableFeaturesRequest getFeaturesRequest, RequestOptions options,
416-
ActionListener<GetSnapshottableFeaturesResponse> listener) {
417-
return restHighLevelClient.performRequestAsyncAndParseEntity(
418-
getFeaturesRequest,
419-
SnapshotRequestConverters::getSnapshottableFeatures,
420-
options,
421-
GetSnapshottableFeaturesResponse::parse,
422-
listener,
423-
emptySet()
424-
);
425-
}
426381
}

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
2424
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
2525
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
26-
import org.elasticsearch.client.snapshots.GetSnapshottableFeaturesRequest;
2726
import org.elasticsearch.common.Strings;
2827

2928
import java.io.IOException;
@@ -191,13 +190,4 @@ static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
191190
request.addParameters(parameters.asMap());
192191
return request;
193192
}
194-
195-
static Request getSnapshottableFeatures(GetSnapshottableFeaturesRequest getSnapshottableFeaturesRequest) {
196-
String endpoint = "/_snapshottable_features";
197-
Request request = new Request(HttpGet.METHOD_NAME, endpoint);
198-
RequestConverters.Params parameters = new RequestConverters.Params();
199-
parameters.withMasterTimeout(getSnapshottableFeaturesRequest.masterNodeTimeout());
200-
request.addParameters(parameters.asMap());
201-
return request;
202-
}
203193
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
/**
1414
* A {@link TimedRequest} to get the list of features available to be included in snapshots in the cluster.
1515
*/
16-
public class GetSnapshottableFeaturesRequest extends TimedRequest {
16+
public class GetFeaturesRequest extends TimedRequest {
1717
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,38 @@
1616
import java.util.List;
1717
import java.util.Objects;
1818

19-
public class GetSnapshottableFeaturesResponse {
19+
public class GetFeaturesResponse {
2020

2121
private final List<SnapshottableFeature> features;
2222

2323
private static final ParseField FEATURES = new ParseField("features");
2424

2525
@SuppressWarnings("unchecked")
26-
private static final ConstructingObjectParser<GetSnapshottableFeaturesResponse, Void> PARSER = new ConstructingObjectParser<>(
27-
"snapshottable_features_response", true, (a, ctx) -> new GetSnapshottableFeaturesResponse((List<SnapshottableFeature>) a[0])
26+
private static final ConstructingObjectParser<GetFeaturesResponse, Void> PARSER = new ConstructingObjectParser<>(
27+
"snapshottable_features_response", true, (a, ctx) -> new GetFeaturesResponse((List<SnapshottableFeature>) a[0])
2828
);
2929

3030
static {
3131
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), SnapshottableFeature::parse, FEATURES);
3232
}
3333

34-
public GetSnapshottableFeaturesResponse(List<SnapshottableFeature> features) {
34+
public GetFeaturesResponse(List<SnapshottableFeature> features) {
3535
this.features = features;
3636
}
3737

3838
public List<SnapshottableFeature> getFeatures() {
3939
return features;
4040
}
4141

42-
public static GetSnapshottableFeaturesResponse parse(XContentParser parser) {
42+
public static GetFeaturesResponse parse(XContentParser parser) {
4343
return PARSER.apply(parser, null);
4444
}
4545

4646
@Override
4747
public boolean equals(Object o) {
4848
if (this == o) return true;
49-
if ((o instanceof GetSnapshottableFeaturesResponse) == false) return false;
50-
GetSnapshottableFeaturesResponse that = (GetSnapshottableFeaturesResponse) o;
49+
if ((o instanceof GetFeaturesResponse) == false) return false;
50+
GetFeaturesResponse that = (GetFeaturesResponse) o;
5151
return getFeatures().equals(that.getFeatures());
5252
}
5353

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.client;
10+
11+
import org.elasticsearch.client.snapshots.GetFeaturesRequest;
12+
import org.elasticsearch.client.snapshots.GetFeaturesResponse;
13+
14+
import java.io.IOException;
15+
16+
import static org.hamcrest.Matchers.greaterThan;
17+
import static org.hamcrest.Matchers.notNullValue;
18+
19+
public class FeaturesIT extends ESRestHighLevelClientTestCase {
20+
public void testGetFeatures() throws IOException {
21+
GetFeaturesRequest request = new GetFeaturesRequest();
22+
23+
GetFeaturesResponse response = execute(request,
24+
highLevelClient().features()::getFeatures, highLevelClient().features()::getFeaturesAsync);
25+
26+
assertThat(response, notNullValue());
27+
assertThat(response.getFeatures(), notNullValue());
28+
assertThat(response.getFeatures().size(), greaterThan(1));
29+
assertTrue(response.getFeatures().stream().anyMatch(feature -> "tasks".equals(feature.getFeatureName())));
30+
}
31+
}

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
2929
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
3030
import org.elasticsearch.action.support.master.AcknowledgedResponse;
31-
import org.elasticsearch.client.snapshots.GetSnapshottableFeaturesRequest;
32-
import org.elasticsearch.client.snapshots.GetSnapshottableFeaturesResponse;
3331
import org.elasticsearch.cluster.metadata.IndexMetadata;
3432
import org.elasticsearch.common.settings.Settings;
3533
import org.elasticsearch.common.xcontent.XContentType;
@@ -52,7 +50,6 @@
5250
import static org.hamcrest.Matchers.equalTo;
5351
import static org.hamcrest.Matchers.greaterThan;
5452
import static org.hamcrest.Matchers.is;
55-
import static org.hamcrest.Matchers.notNullValue;
5653

5754
public class SnapshotIT extends ESRestHighLevelClientTestCase {
5855

@@ -384,18 +381,6 @@ public void testCloneSnapshot() throws IOException {
384381
assertTrue(response.isAcknowledged());
385382
}
386383

387-
public void testGetFeatures() throws IOException {
388-
GetSnapshottableFeaturesRequest request = new GetSnapshottableFeaturesRequest();
389-
390-
GetSnapshottableFeaturesResponse response = execute(request,
391-
highLevelClient().snapshot()::getFeatures, highLevelClient().snapshot()::getFeaturesAsync);
392-
393-
assertThat(response, notNullValue());
394-
assertThat(response.getFeatures(), notNullValue());
395-
assertThat(response.getFeatures().size(), greaterThan(1));
396-
assertTrue(response.getFeatures().stream().anyMatch(feature -> "tasks".equals(feature.getFeatureName())));
397-
}
398-
399384
private static Map<String, Object> randomUserMetadata() {
400385
if (randomBoolean()) {
401386
return null;
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@
2121
import static org.hamcrest.Matchers.in;
2222
import static org.hamcrest.Matchers.is;
2323

24-
public class GetSnapshottableFeaturesResponseTests extends AbstractResponseTestCase<
25-
org.elasticsearch.action.admin.cluster.snapshots.features.GetSnapshottableFeaturesResponse,
26-
GetSnapshottableFeaturesResponse> {
24+
public class GetFeaturesResponseTests extends AbstractResponseTestCase<
25+
org.elasticsearch.action.admin.cluster.snapshots.features.GetSnapshottableFeaturesResponse, GetFeaturesResponse> {
2726

2827
@Override
2928
protected org.elasticsearch.action.admin.cluster.snapshots.features.GetSnapshottableFeaturesResponse createServerTestInstance(
@@ -41,14 +40,14 @@ protected org.elasticsearch.action.admin.cluster.snapshots.features.GetSnapshott
4140
}
4241

4342
@Override
44-
protected GetSnapshottableFeaturesResponse doParseToClientInstance(XContentParser parser) throws IOException {
45-
return GetSnapshottableFeaturesResponse.parse(parser);
43+
protected GetFeaturesResponse doParseToClientInstance(XContentParser parser) throws IOException {
44+
return GetFeaturesResponse.parse(parser);
4645
}
4746

4847
@Override
4948
protected void assertInstances(
5049
org.elasticsearch.action.admin.cluster.snapshots.features.GetSnapshottableFeaturesResponse serverTestInstance,
51-
GetSnapshottableFeaturesResponse clientInstance
50+
GetFeaturesResponse clientInstance
5251
) {
5352
assertNotNull(serverTestInstance.getSnapshottableFeatures());
5453
assertNotNull(serverTestInstance.getSnapshottableFeatures());

0 commit comments

Comments
 (0)