HLRC: add enable and disable user API support (#33481)

This change adds support for enable and disable user APIs to the high
level rest client. There is a common request base class for both
requests with specific requests that simplify the use of these APIs.

The response for these APIs is simply an empty object so a new response
class has been created for cases where we expect an empty response to
be returned.

Finally, the put user documentation has been moved to the proper
location that is not within an x-pack sub directory and the document
tags no longer contain x-pack.

See #29827
This commit is contained in:
Jay Modi 2018-09-07 11:51:37 -06:00 committed by GitHub
parent 944868908c
commit 9d16a7b7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 535 additions and 28 deletions

View File

@ -20,8 +20,11 @@
package org.elasticsearch.client;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.security.DisableUserRequest;
import org.elasticsearch.client.security.EnableUserRequest;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.PutUserResponse;
import org.elasticsearch.client.security.EmptyResponse;
import java.io.IOException;
@ -66,4 +69,60 @@ public final class SecurityClient {
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::putUser, options,
PutUserResponse::fromXContent, listener, emptySet());
}
/**
* Enable a native realm or built-in user synchronously.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html">
* the docs</a> for more.
* @param request the request with the user to enable
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response from the enable user call
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public EmptyResponse enableUser(EnableUserRequest request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::enableUser, options,
EmptyResponse::fromXContent, emptySet());
}
/**
* Enable a native realm or built-in user asynchronously.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html">
* the docs</a> for more.
* @param request the request with the user to enable
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener the listener to be notified upon request completion
*/
public void enableUserAsync(EnableUserRequest request, RequestOptions options,
ActionListener<EmptyResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::enableUser, options,
EmptyResponse::fromXContent, listener, emptySet());
}
/**
* Disable a native realm or built-in user synchronously.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html">
* the docs</a> for more.
* @param request the request with the user to disable
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response from the enable user call
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public EmptyResponse disableUser(DisableUserRequest request, RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::disableUser, options,
EmptyResponse::fromXContent, emptySet());
}
/**
* Disable a native realm or built-in user asynchronously.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html">
* the docs</a> for more.
* @param request the request with the user to disable
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @param listener the listener to be notified upon request completion
*/
public void disableUserAsync(DisableUserRequest request, RequestOptions options,
ActionListener<EmptyResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::disableUser, options,
EmptyResponse::fromXContent, listener, emptySet());
}
}

View File

@ -20,14 +20,17 @@
package org.elasticsearch.client;
import org.apache.http.client.methods.HttpPut;
import org.elasticsearch.client.security.DisableUserRequest;
import org.elasticsearch.client.security.EnableUserRequest;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.SetUserEnabledRequest;
import java.io.IOException;
import static org.elasticsearch.client.RequestConverters.REQUEST_BODY_CONTENT_TYPE;
import static org.elasticsearch.client.RequestConverters.createEntity;
public final class SecurityRequestConverters {
final class SecurityRequestConverters {
private SecurityRequestConverters() {}
@ -42,4 +45,24 @@ public final class SecurityRequestConverters {
params.withRefreshPolicy(putUserRequest.getRefreshPolicy());
return request;
}
static Request enableUser(EnableUserRequest enableUserRequest) {
return setUserEnabled(enableUserRequest);
}
static Request disableUser(DisableUserRequest disableUserRequest) {
return setUserEnabled(disableUserRequest);
}
private static Request setUserEnabled(SetUserEnabledRequest setUserEnabledRequest) {
String endpoint = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_xpack/security/user")
.addPathPart(setUserEnabledRequest.getUsername())
.addPathPart(setUserEnabledRequest.isEnabled() ? "_enable" : "_disable")
.build();
Request request = new Request(HttpPut.METHOD_NAME, endpoint);
RequestConverters.Params params = new RequestConverters.Params(request);
params.withRefreshPolicy(setUserEnabledRequest.getRefreshPolicy());
return request;
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.security;
/**
* Request object to disable a native realm or built-in user.
*/
public final class DisableUserRequest extends SetUserEnabledRequest {
public DisableUserRequest(String username, RefreshPolicy refreshPolicy) {
super(false, username, refreshPolicy);
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.security;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
/**
* Response for a request which simply returns an empty object.
*/
public final class EmptyResponse {
private static final ObjectParser<EmptyResponse, Void> PARSER = new ObjectParser<>("empty_response", false, EmptyResponse::new);
public static EmptyResponse fromXContent(XContentParser parser) throws IOException {
return PARSER.parse(parser, null);
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.security;
/**
* Request object to enable a native realm or built-in user.
*/
public final class EnableUserRequest extends SetUserEnabledRequest {
public EnableUserRequest(String username, RefreshPolicy refreshPolicy) {
super(true, username, refreshPolicy);
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.security;
import org.elasticsearch.client.Validatable;
import java.util.Objects;
/**
* Abstract request object to enable or disable a built-in or native user.
*/
public abstract class SetUserEnabledRequest implements Validatable {
private final boolean enabled;
private final String username;
private final RefreshPolicy refreshPolicy;
SetUserEnabledRequest(boolean enabled, String username, RefreshPolicy refreshPolicy) {
this.enabled = enabled;
this.username = Objects.requireNonNull(username, "username is required");
this.refreshPolicy = refreshPolicy == null ? RefreshPolicy.getDefault() : refreshPolicy;
}
public boolean isEnabled() {
return enabled;
}
public String getUsername() {
return username;
}
public RefreshPolicy getRefreshPolicy() {
return refreshPolicy;
}
}

View File

@ -20,6 +20,8 @@
package org.elasticsearch.client;
import org.apache.http.client.methods.HttpPut;
import org.elasticsearch.client.security.DisableUserRequest;
import org.elasticsearch.client.security.EnableUserRequest;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.RefreshPolicy;
import org.elasticsearch.test.ESTestCase;
@ -53,12 +55,7 @@ public class SecurityRequestConvertersTests extends ESTestCase {
}
final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values());
final Map<String, String> expectedParams;
if (refreshPolicy != RefreshPolicy.NONE) {
expectedParams = Collections.singletonMap("refresh", refreshPolicy.getValue());
} else {
expectedParams = Collections.emptyMap();
}
final Map<String, String> expectedParams = getExpectedParamsFromRefreshPolicy(refreshPolicy);
PutUserRequest putUserRequest = new PutUserRequest(username, password, roles, fullName, email, enabled, metadata, refreshPolicy);
Request request = SecurityRequestConverters.putUser(putUserRequest);
@ -67,4 +64,36 @@ public class SecurityRequestConvertersTests extends ESTestCase {
assertEquals(expectedParams, request.getParameters());
assertToXContentBody(putUserRequest, request.getEntity());
}
public void testEnableUser() {
final String username = randomAlphaOfLengthBetween(1, 12);
final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values());
final Map<String, String> expectedParams = getExpectedParamsFromRefreshPolicy(refreshPolicy);
EnableUserRequest enableUserRequest = new EnableUserRequest(username, refreshPolicy);
Request request = SecurityRequestConverters.enableUser(enableUserRequest);
assertEquals(HttpPut.METHOD_NAME, request.getMethod());
assertEquals("/_xpack/security/user/" + username + "/_enable", request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertNull(request.getEntity());
}
public void testDisableUser() {
final String username = randomAlphaOfLengthBetween(1, 12);
final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values());
final Map<String, String> expectedParams = getExpectedParamsFromRefreshPolicy(refreshPolicy);
DisableUserRequest disableUserRequest = new DisableUserRequest(username, refreshPolicy);
Request request = SecurityRequestConverters.disableUser(disableUserRequest);
assertEquals(HttpPut.METHOD_NAME, request.getMethod());
assertEquals("/_xpack/security/user/" + username + "/_disable", request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertNull(request.getEntity());
}
private static Map<String, String> getExpectedParamsFromRefreshPolicy(RefreshPolicy refreshPolicy) {
if (refreshPolicy != RefreshPolicy.NONE) {
return Collections.singletonMap("refresh", refreshPolicy.getValue());
} else {
return Collections.emptyMap();
}
}
}

View File

@ -24,9 +24,12 @@ import org.elasticsearch.action.LatchedActionListener;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.security.DisableUserRequest;
import org.elasticsearch.client.security.EnableUserRequest;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.PutUserResponse;
import org.elasticsearch.client.security.RefreshPolicy;
import org.elasticsearch.client.security.EmptyResponse;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
@ -38,16 +41,16 @@ public class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
RestHighLevelClient client = highLevelClient();
{
//tag::x-pack-put-user-execute
//tag::put-user-execute
char[] password = new char[] { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
PutUserRequest request =
new PutUserRequest("example", password, Collections.singletonList("superuser"), null, null, true, null, RefreshPolicy.NONE);
PutUserResponse response = client.security().putUser(request, RequestOptions.DEFAULT);
//end::x-pack-put-user-execute
//end::put-user-execute
//tag::x-pack-put-user-response
//tag::put-user-response
boolean isCreated = response.isCreated(); // <1>
//end::x-pack-put-user-response
//end::put-user-response
assertTrue(isCreated);
}
@ -56,7 +59,7 @@ public class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
char[] password = new char[] { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
PutUserRequest request = new PutUserRequest("example2", password, Collections.singletonList("superuser"), null, null, true,
null, RefreshPolicy.NONE);
// tag::x-pack-put-user-execute-listener
// tag::put-user-execute-listener
ActionListener<PutUserResponse> listener = new ActionListener<PutUserResponse>() {
@Override
public void onResponse(PutUserResponse response) {
@ -68,15 +71,104 @@ public class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
// <2>
}
};
// end::x-pack-put-user-execute-listener
// end::put-user-execute-listener
// Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
// tag::x-pack-put-user-execute-async
// tag::put-user-execute-async
client.security().putUserAsync(request, RequestOptions.DEFAULT, listener); // <1>
// end::x-pack-put-user-execute-async
// end::put-user-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}
public void testEnableUser() throws Exception {
RestHighLevelClient client = highLevelClient();
char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
PutUserRequest putUserRequest = new PutUserRequest("enable_user", password, Collections.singletonList("superuser"), null,
null, true, null, RefreshPolicy.IMMEDIATE);
PutUserResponse putUserResponse = client.security().putUser(putUserRequest, RequestOptions.DEFAULT);
assertTrue(putUserResponse.isCreated());
{
//tag::enable-user-execute
EnableUserRequest request = new EnableUserRequest("enable_user", RefreshPolicy.NONE);
EmptyResponse response = client.security().enableUser(request, RequestOptions.DEFAULT);
//end::enable-user-execute
assertNotNull(response);
}
{
//tag::enable-user-execute-listener
EnableUserRequest request = new EnableUserRequest("enable_user", RefreshPolicy.NONE);
ActionListener<EmptyResponse> listener = new ActionListener<EmptyResponse>() {
@Override
public void onResponse(EmptyResponse setUserEnabledResponse) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
};
//end::enable-user-execute-listener
// Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
// tag::enable-user-execute-async
client.security().enableUserAsync(request, RequestOptions.DEFAULT, listener); // <1>
// end::enable-user-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}
}
public void testDisableUser() throws Exception {
RestHighLevelClient client = highLevelClient();
char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
PutUserRequest putUserRequest = new PutUserRequest("disable_user", password, Collections.singletonList("superuser"), null,
null, true, null, RefreshPolicy.IMMEDIATE);
PutUserResponse putUserResponse = client.security().putUser(putUserRequest, RequestOptions.DEFAULT);
assertTrue(putUserResponse.isCreated());
{
//tag::disable-user-execute
DisableUserRequest request = new DisableUserRequest("disable_user", RefreshPolicy.NONE);
EmptyResponse response = client.security().disableUser(request, RequestOptions.DEFAULT);
//end::disable-user-execute
assertNotNull(response);
}
{
//tag::disable-user-execute-listener
DisableUserRequest request = new DisableUserRequest("disable_user", RefreshPolicy.NONE);
ActionListener<EmptyResponse> listener = new ActionListener<EmptyResponse>() {
@Override
public void onResponse(EmptyResponse setUserEnabledResponse) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
};
//end::disable-user-execute-listener
// Replace the empty listener by a blocking listener in test
final CountDownLatch latch = new CountDownLatch(1);
listener = new LatchedActionListener<>(listener, latch);
// tag::disable-user-execute-async
client.security().disableUserAsync(request, RequestOptions.DEFAULT, listener); // <1>
// end::disable-user-execute-async
assertTrue(latch.await(30L, TimeUnit.SECONDS));
}

View File

@ -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.security;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParseException;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import static org.hamcrest.Matchers.containsString;
public class EmptyResponseTests extends ESTestCase {
public void testParseFromXContent() throws IOException {
try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY,
DeprecationHandler.THROW_UNSUPPORTED_OPERATION, "{}")) {
EmptyResponse response = EmptyResponse.fromXContent(parser);
assertNotNull(response);
}
try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY,
DeprecationHandler.THROW_UNSUPPORTED_OPERATION, "{\"foo\": \"bar\"}")) {
XContentParseException exception =
expectThrows(XContentParseException.class, () -> EmptyResponse.fromXContent(parser));
assertThat(exception.getMessage(), containsString("field [foo]"));
}
}
}

View File

@ -0,0 +1,46 @@
[[java-rest-high-security-disable-user]]
=== Disable User API
[[java-rest-high-security-disable-user-execution]]
==== Execution
Disabling a user can be performed using the `security().disableUser()`
method:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute]
--------------------------------------------------
[[java-rest-high-security-disable-user-response]]
==== Response
The returned `EmptyResponse` does not contain any fields. The return of this
response indicates a successful request.
[[java-rest-high-security-disable-user-async]]
==== Asynchronous Execution
This request can be executed asynchronously:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute-async]
--------------------------------------------------
<1> The `DisableUser` request to execute and the `ActionListener` to use when
the execution completes.
The asynchronous method does not block and returns immediately. Once the request
has completed the `ActionListener` is called back using the `onResponse` method
if the execution successfully completed or using the `onFailure` method if
it failed.
A typical listener for a `EmptyResponse` looks like:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute-listener]
--------------------------------------------------
<1> Called when the execution is successfully completed. The response is
provided as an argument.
<2> Called in case of failure. The raised exception is provided as an argument.

View File

@ -0,0 +1,46 @@
[[java-rest-high-security-enable-user]]
=== Enable User API
[[java-rest-high-security-enable-user-execution]]
==== Execution
Enabling a disabled user can be performed using the `security().enableUser()`
method:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute]
--------------------------------------------------
[[java-rest-high-security-enable-user-response]]
==== Response
The returned `EmptyResponse` does not contain any fields. The return of this
response indicates a successful request.
[[java-rest-high-security-enable-user-async]]
==== Asynchronous Execution
This request can be executed asynchronously:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute-async]
--------------------------------------------------
<1> The `EnableUser` request to execute and the `ActionListener` to use when
the execution completes.
The asynchronous method does not block and returns immediately. Once the request
has completed the `ActionListener` is called back using the `onResponse` method
if the execution successfully completed or using the `onFailure` method if
it failed.
A typical listener for a `EmptyResponse` looks like:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute-listener]
--------------------------------------------------
<1> Called when the execution is successfully completed. The response is
provided as an argument.
<2> Called in case of failure. The raised exception is provided as an argument.

View File

@ -1,7 +1,7 @@
[[java-rest-high-x-pack-security-put-user]]
=== X-Pack Put User API
[[java-rest-high-security-put-user]]
=== Put User API
[[java-rest-high-x-pack-security-put-user-execution]]
[[java-rest-high-security-put-user-execution]]
==== Execution
Creating and updating a user can be performed using the `security().putUser()`
@ -9,10 +9,10 @@ method:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-execute]
include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute]
--------------------------------------------------
[[java-rest-high-x-pack-security-put-user-response]]
[[java-rest-high-security-put-user-response]]
==== Response
The returned `PutUserResponse` contains a single field, `created`. This field
@ -20,21 +20,21 @@ serves as an indication if a user was created or if an existing entry was update
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-response]
include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-response]
--------------------------------------------------
<1> `created` is a boolean indicating whether the user was created or updated
[[java-rest-high-x-pack-security-put-user-async]]
[[java-rest-high-security-put-user-async]]
==== Asynchronous Execution
This request can be executed asynchronously:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-execute-async]
include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute-async]
--------------------------------------------------
<1> The `PutUserResponse` to execute and the `ActionListener` to use when
the execution completes
<1> The `PutUserRequest` to execute and the `ActionListener` to use when
the execution completes.
The asynchronous method does not block and returns immediately. Once the request
has completed the `ActionListener` is called back using the `onResponse` method
@ -45,8 +45,8 @@ A typical listener for a `PutUserResponse` looks like:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-execute-listener]
include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute-listener]
--------------------------------------------------
<1> Called when the execution is successfully completed. The response is
provided as an argument
<2> Called in case of failure. The raised exception is provided as an argument
provided as an argument.
<2> Called in case of failure. The raised exception is provided as an argument.

View File

@ -248,6 +248,18 @@ The Java High Level REST Client supports the following Migration APIs:
include::migration/get-assistance.asciidoc[]
== Security APIs
The Java High Level REST Client supports the following Security APIs:
* <<java-rest-high-security-put-user>>
* <<java-rest-high-security-enable-user>>
* <<java-rest-high-security-disable-user>>
include::security/put-user.asciidoc[]
include::security/enable-user.asciidoc[]
include::security/disable-user.asciidoc[]
== Watcher APIs
The Java High Level REST Client supports the following Watcher APIs: