Skip to content

Commit 0de5396

Browse files
committed
Deprecate HLRC EmptyResponse used by security (#37540)
The EmptyResponse is essentially the same as returning a boolean, which is done in other places. This commit deprecates all the existing EmptyResponse methods and creates new boolean methods that have method params reordered so they can exist with the deprecated methods. A followup PR in master will remove the existing deprecated methods, fix the parameter ordering and deprecate the incorrectly ordered parameter methods. Relates #36938
1 parent ccac370 commit 0de5396

File tree

9 files changed

+161
-39
lines changed

9 files changed

+161
-39
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,7 @@ private static RequestOptions optionsForHeaders(Header[] headers) {
20622062
return options.build();
20632063
}
20642064

2065-
static boolean convertExistsResponse(Response response) {
2065+
protected static boolean convertExistsResponse(Response response) {
20662066
return response.getStatusLine().getStatusCode() == 200;
20672067
}
20682068

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

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,29 @@ public void getRoleMappingsAsync(final GetRoleMappingsRequest request, final Req
237237
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
238238
* @return the response from the enable user call
239239
* @throws IOException in case there is a problem sending the request or parsing back the response
240+
* @deprecated use {@link #enableUser(RequestOptions, EnableUserRequest)} instead
240241
*/
242+
@Deprecated
241243
public EmptyResponse enableUser(EnableUserRequest request, RequestOptions options) throws IOException {
242244
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::enableUser, options,
243245
EmptyResponse::fromXContent, emptySet());
244246
}
245247

248+
/**
249+
* Enable a native realm or built-in user synchronously.
250+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html">
251+
* the docs</a> for more.
252+
*
253+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
254+
* @param request the request with the user to enable
255+
* @return {@code true} if the request succeeded (the user is enabled)
256+
* @throws IOException in case there is a problem sending the request or parsing back the response
257+
*/
258+
public boolean enableUser(RequestOptions options, EnableUserRequest request) throws IOException {
259+
return restHighLevelClient.performRequest(request, SecurityRequestConverters::enableUser, options,
260+
RestHighLevelClient::convertExistsResponse, emptySet());
261+
}
262+
246263
/**
247264
* Enable a native realm or built-in user asynchronously.
248265
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html">
@@ -251,13 +268,30 @@ public EmptyResponse enableUser(EnableUserRequest request, RequestOptions option
251268
* @param request the request with the user to enable
252269
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
253270
* @param listener the listener to be notified upon request completion
271+
* @deprecated use {@link #enableUserAsync(RequestOptions, EnableUserRequest, ActionListener)} instead
254272
*/
273+
@Deprecated
255274
public void enableUserAsync(EnableUserRequest request, RequestOptions options,
256275
ActionListener<EmptyResponse> listener) {
257276
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::enableUser, options,
258277
EmptyResponse::fromXContent, listener, emptySet());
259278
}
260279

280+
/**
281+
* Enable a native realm or built-in user asynchronously.
282+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html">
283+
* the docs</a> for more.
284+
*
285+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
286+
* @param request the request with the user to enable
287+
* @param listener the listener to be notified upon request completion
288+
*/
289+
public void enableUserAsync(RequestOptions options, EnableUserRequest request,
290+
ActionListener<Boolean> listener) {
291+
restHighLevelClient.performRequestAsync(request, SecurityRequestConverters::enableUser, options,
292+
RestHighLevelClient::convertExistsResponse, listener, emptySet());
293+
}
294+
261295
/**
262296
* Disable a native realm or built-in user synchronously.
263297
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html">
@@ -267,12 +301,29 @@ public void enableUserAsync(EnableUserRequest request, RequestOptions options,
267301
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
268302
* @return the response from the enable user call
269303
* @throws IOException in case there is a problem sending the request or parsing back the response
304+
* @deprecated use {@link #disableUser(RequestOptions, DisableUserRequest)} instead
270305
*/
306+
@Deprecated
271307
public EmptyResponse disableUser(DisableUserRequest request, RequestOptions options) throws IOException {
272308
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::disableUser, options,
273309
EmptyResponse::fromXContent, emptySet());
274310
}
275311

312+
/**
313+
* Disable a native realm or built-in user synchronously.
314+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html">
315+
* the docs</a> for more.
316+
*
317+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
318+
* @param request the request with the user to disable
319+
* @return {@code true} if the request succeeded (the user is disabled)
320+
* @throws IOException in case there is a problem sending the request or parsing back the response
321+
*/
322+
public boolean disableUser(RequestOptions options, DisableUserRequest request) throws IOException {
323+
return restHighLevelClient.performRequest(request, SecurityRequestConverters::disableUser, options,
324+
RestHighLevelClient::convertExistsResponse, emptySet());
325+
}
326+
276327
/**
277328
* Disable a native realm or built-in user asynchronously.
278329
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html">
@@ -281,13 +332,30 @@ public EmptyResponse disableUser(DisableUserRequest request, RequestOptions opti
281332
* @param request the request with the user to disable
282333
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
283334
* @param listener the listener to be notified upon request completion
335+
* @deprecated use {@link #disableUserAsync(RequestOptions, DisableUserRequest, ActionListener)} instead
284336
*/
337+
@Deprecated
285338
public void disableUserAsync(DisableUserRequest request, RequestOptions options,
286339
ActionListener<EmptyResponse> listener) {
287340
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::disableUser, options,
288341
EmptyResponse::fromXContent, listener, emptySet());
289342
}
290343

344+
/**
345+
* Disable a native realm or built-in user asynchronously.
346+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html">
347+
* the docs</a> for more.
348+
*
349+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
350+
* @param request the request with the user to disable
351+
* @param listener the listener to be notified upon request completion
352+
*/
353+
public void disableUserAsync(RequestOptions options, DisableUserRequest request,
354+
ActionListener<Boolean> listener) {
355+
restHighLevelClient.performRequestAsync(request, SecurityRequestConverters::disableUser, options,
356+
RestHighLevelClient::convertExistsResponse, listener, emptySet());
357+
}
358+
291359
/**
292360
* Authenticate the current user and return all the information about the authenticated user.
293361
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-authenticate.html">
@@ -457,12 +525,29 @@ public void getSslCertificatesAsync(RequestOptions options, ActionListener<GetSs
457525
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
458526
* @return the response from the change user password call
459527
* @throws IOException in case there is a problem sending the request or parsing back the response
528+
* @deprecated use {@link #changePassword(RequestOptions, ChangePasswordRequest)} instead
460529
*/
530+
@Deprecated
461531
public EmptyResponse changePassword(ChangePasswordRequest request, RequestOptions options) throws IOException {
462532
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::changePassword, options,
463533
EmptyResponse::fromXContent, emptySet());
464534
}
465535

536+
/**
537+
* Change the password of a user of a native realm or built-in user synchronously.
538+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-change-password.html">
539+
* the docs</a> for more.
540+
*
541+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
542+
* @param request the request with the user's new password
543+
* @return {@code true} if the request succeeded (the new password was set)
544+
* @throws IOException in case there is a problem sending the request or parsing back the response
545+
*/
546+
public boolean changePassword(RequestOptions options, ChangePasswordRequest request) throws IOException {
547+
return restHighLevelClient.performRequest(request, SecurityRequestConverters::changePassword, options,
548+
RestHighLevelClient::convertExistsResponse, emptySet());
549+
}
550+
466551
/**
467552
* Change the password of a user of a native realm or built-in user asynchronously.
468553
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-change-password.html">
@@ -471,13 +556,31 @@ public EmptyResponse changePassword(ChangePasswordRequest request, RequestOption
471556
* @param request the request with the user's new password
472557
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
473558
* @param listener the listener to be notified upon request completion
559+
* @deprecated use {@link #changePasswordAsync(RequestOptions, ChangePasswordRequest, ActionListener)} instead
474560
*/
561+
@Deprecated
475562
public void changePasswordAsync(ChangePasswordRequest request, RequestOptions options,
476563
ActionListener<EmptyResponse> listener) {
477564
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::changePassword, options,
478565
EmptyResponse::fromXContent, listener, emptySet());
479566
}
480567

568+
/**
569+
* Change the password of a user of a native realm or built-in user asynchronously.
570+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-change-password.html">
571+
* the docs</a> for more.
572+
*
573+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
574+
* @param request the request with the user's new password
575+
* @param listener the listener to be notified upon request completion
576+
*/
577+
public void changePasswordAsync(RequestOptions options, ChangePasswordRequest request,
578+
ActionListener<Boolean> listener) {
579+
restHighLevelClient.performRequestAsync(request, SecurityRequestConverters::changePassword, options,
580+
RestHighLevelClient::convertExistsResponse, listener, emptySet());
581+
}
582+
583+
481584
/**
482585
* Delete a role mapping.
483586
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-delete-role-mapping.html">

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626

2727
/**
2828
* Response for a request which simply returns an empty object.
29+
@deprecated Use a boolean instead of this class
2930
*/
31+
@Deprecated
3032
public final class EmptyResponse {
3133

3234
private static final ObjectParser<EmptyResponse, Void> PARSER = new ObjectParser<>("empty_response", false, EmptyResponse::new);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ private static RequestOptions optionsForNodeName(String nodeName) {
127127
*/
128128
@SuppressForbidden(reason = "We're forced to uses Class#getDeclaredMethods() here because this test checks protected methods")
129129
public void testMethodsVisibility() {
130-
final String[] methodNames = new String[]{"parseEntity",
130+
final String[] methodNames = new String[]{"convertExistsResponse",
131+
"parseEntity",
131132
"parseResponseException",
132133
"performRequest",
133134
"performRequestAndParseEntity",

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

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,10 @@ public void testApiNamingConventions() throws Exception {
731731
"nodes.reload_secure_settings",
732732
"search_shards",
733733
};
734+
List<String> booleanReturnMethods = Arrays.asList(
735+
"security.enable_user",
736+
"security.disable_user",
737+
"security.change_password");
734738
Set<String> deprecatedMethods = new HashSet<>();
735739
deprecatedMethods.add("indices.force_merge");
736740
deprecatedMethods.add("multi_get");
@@ -754,6 +758,7 @@ public void testApiNamingConventions() throws Exception {
754758
.map(method -> Tuple.tuple(toSnakeCase(method.getName()), method))
755759
.flatMap(tuple -> tuple.v2().getReturnType().getName().endsWith("Client")
756760
? getSubClientMethods(tuple.v1(), tuple.v2().getReturnType()) : Stream.of(tuple))
761+
.filter(tuple -> tuple.v2().getAnnotation(Deprecated.class) == null)
757762
.collect(Collectors.groupingBy(Tuple::v1,
758763
Collectors.mapping(Tuple::v2, Collectors.toSet())));
759764

@@ -771,7 +776,7 @@ public void testApiNamingConventions() throws Exception {
771776
} else if (isSubmitTaskMethod(apiName)) {
772777
assertSubmitTaskMethod(methods, method, apiName, restSpec);
773778
} else {
774-
assertSyncMethod(method, apiName);
779+
assertSyncMethod(method, apiName, booleanReturnMethods);
775780
apiUnsupported.remove(apiName);
776781
if (apiSpec.contains(apiName) == false) {
777782
if (deprecatedMethods.contains(apiName)) {
@@ -808,9 +813,9 @@ public void testApiNamingConventions() throws Exception {
808813
assertThat("Some API are not supported but they should be: " + apiUnsupported, apiUnsupported.size(), equalTo(0));
809814
}
810815

811-
private static void assertSyncMethod(Method method, String apiName) {
816+
private static void assertSyncMethod(Method method, String apiName, List<String> booleanReturnMethods) {
812817
//A few methods return a boolean rather than a response object
813-
if (apiName.equals("ping") || apiName.contains("exist")) {
818+
if (apiName.equals("ping") || apiName.contains("exist") || booleanReturnMethods.contains(apiName)) {
814819
assertThat("the return type for method [" + method + "] is incorrect",
815820
method.getReturnType().getSimpleName(), equalTo("boolean"));
816821
} else {
@@ -829,10 +834,18 @@ private static void assertSyncMethod(Method method, String apiName) {
829834
method.getParameterTypes()[0], equalTo(RequestOptions.class));
830835
} else {
831836
assertEquals("incorrect number of arguments for method [" + method + "]", 2, method.getParameterTypes().length);
832-
assertThat("the first parameter to method [" + method + "] is the wrong type",
833-
method.getParameterTypes()[0].getSimpleName(), endsWith("Request"));
834-
assertThat("the second parameter to method [" + method + "] is the wrong type",
835-
method.getParameterTypes()[1], equalTo(RequestOptions.class));
837+
// This is no longer true for all methods. Some methods can contain these 2 args backwards because of deprecation
838+
if (method.getParameterTypes()[0].equals(RequestOptions.class)) {
839+
assertThat("the first parameter to method [" + method + "] is the wrong type",
840+
method.getParameterTypes()[0], equalTo(RequestOptions.class));
841+
assertThat("the second parameter to method [" + method + "] is the wrong type",
842+
method.getParameterTypes()[1].getSimpleName(), endsWith("Request"));
843+
} else {
844+
assertThat("the first parameter to method [" + method + "] is the wrong type",
845+
method.getParameterTypes()[0].getSimpleName(), endsWith("Request"));
846+
assertThat("the second parameter to method [" + method + "] is the wrong type",
847+
method.getParameterTypes()[1], equalTo(RequestOptions.class));
848+
}
836849
}
837850
}
838851

@@ -847,10 +860,18 @@ private static void assertAsyncMethod(Map<String, Set<Method>> methods, Method m
847860
assertThat(method.getParameterTypes()[1], equalTo(ActionListener.class));
848861
} else {
849862
assertEquals("async method [" + method + "] has the wrong number of arguments", 3, method.getParameterTypes().length);
850-
assertThat("the first parameter to async method [" + method + "] should be a request type",
851-
method.getParameterTypes()[0].getSimpleName(), endsWith("Request"));
852-
assertThat("the second parameter to async method [" + method + "] is the wrong type",
853-
method.getParameterTypes()[1], equalTo(RequestOptions.class));
863+
// This is no longer true for all methods. Some methods can contain these 2 args backwards because of deprecation
864+
if (method.getParameterTypes()[0].equals(RequestOptions.class)) {
865+
assertThat("the first parameter to async method [" + method + "] should be a request type",
866+
method.getParameterTypes()[0], equalTo(RequestOptions.class));
867+
assertThat("the second parameter to async method [" + method + "] is the wrong type",
868+
method.getParameterTypes()[1].getSimpleName(), endsWith("Request"));
869+
} else {
870+
assertThat("the first parameter to async method [" + method + "] should be a request type",
871+
method.getParameterTypes()[0].getSimpleName(), endsWith("Request"));
872+
assertThat("the second parameter to async method [" + method + "] is the wrong type",
873+
method.getParameterTypes()[1], equalTo(RequestOptions.class));
874+
}
854875
assertThat("the third parameter to async method [" + method + "] is the wrong type",
855876
method.getParameterTypes()[2], equalTo(ActionListener.class));
856877
}

0 commit comments

Comments
 (0)