diff --git a/client/rest-high-level/build.gradle b/client/rest-high-level/build.gradle index c608d7c91f16e..bfe7c3d956cd2 100644 --- a/client/rest-high-level/build.gradle +++ b/client/rest-high-level/build.gradle @@ -76,6 +76,8 @@ forbiddenApisMain { addSignatureFiles 'http-signatures' signaturesFiles += files('src/main/resources/forbidden/rest-high-level-signatures.txt') } +File nodeCert = file("./testnode.crt") +File nodeTrustStore = file("./testnode.jks") integTestRunner { systemProperty 'tests.rest.cluster.username', System.getProperty('tests.rest.cluster.username', 'test_user') @@ -85,11 +87,17 @@ integTestRunner { integTestCluster { setting 'xpack.license.self_generated.type', 'trial' setting 'xpack.security.enabled', 'true' + // Truststore settings are not used since TLS is not enabled. Included for testing the get certificates API + setting 'xpack.ssl.certificate_authorities', 'testnode.crt' + setting 'xpack.security.transport.ssl.truststore.path', 'testnode.jks' + setting 'xpack.security.transport.ssl.truststore.password', 'testnode' setupCommand 'setupDummyUser', 'bin/elasticsearch-users', 'useradd', System.getProperty('tests.rest.cluster.username', 'test_user'), '-p', System.getProperty('tests.rest.cluster.password', 'test-password'), '-r', 'superuser' + extraConfigFile nodeCert.name, nodeCert + extraConfigFile nodeTrustStore.name, nodeTrustStore waitCondition = { node, ant -> File tmpFile = new File(node.cwd, 'wait.success') ant.get(src: "http://${node.httpUri()}/_cluster/health?wait_for_nodes=>=${numNodes}&wait_for_status=yellow", diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java index 7192d82f474a8..8afaa3551ad88 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java @@ -22,6 +22,8 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.client.security.DisableUserRequest; import org.elasticsearch.client.security.EnableUserRequest; +import org.elasticsearch.client.security.GetSslCertificatesRequest; +import org.elasticsearch.client.security.GetSslCertificatesResponse; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.PutUserResponse; import org.elasticsearch.client.security.EmptyResponse; @@ -133,6 +135,33 @@ public void disableUserAsync(DisableUserRequest request, RequestOptions options, EmptyResponse::fromXContent, listener, emptySet()); } + /** + * Synchronously retrieve the X.509 certificates that are used to encrypt communications in an Elasticsearch cluster. + * See + * the docs for more. + * + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response from the get certificates call + * @throws IOException in case there is a problem sending the request or parsing back the response + */ + public GetSslCertificatesResponse getSslCertificates(RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(GetSslCertificatesRequest.INSTANCE, GetSslCertificatesRequest::getRequest, + options, GetSslCertificatesResponse::fromXContent, emptySet()); + } + + /** + * Asynchronously retrieve the X.509 certificates that are used to encrypt communications in an Elasticsearch cluster. + * See + * the docs for more. + * + * @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 getSslCertificatesAsync(RequestOptions options, ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(GetSslCertificatesRequest.INSTANCE, GetSslCertificatesRequest::getRequest, + options, GetSslCertificatesResponse::fromXContent, listener, emptySet()); + } + /** * Change the password of a user of a native realm or built-in user synchronously. * See diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetSslCertificatesRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetSslCertificatesRequest.java new file mode 100644 index 0000000000000..c4dbef4e422b6 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetSslCertificatesRequest.java @@ -0,0 +1,49 @@ +/* + * 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.apache.http.client.methods.HttpGet; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Validatable; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; + +/** + * Request object to retrieve the X.509 certificates that are used to encrypt communications in an Elasticsearch cluster. + */ +public final class GetSslCertificatesRequest implements Validatable, ToXContentObject { + + public static final GetSslCertificatesRequest INSTANCE = new GetSslCertificatesRequest(); + private final Request request; + + private GetSslCertificatesRequest() { + request = new Request(HttpGet.METHOD_NAME, "/_xpack/ssl/certificates"); + } + + public Request getRequest() { + return request; + } + + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return builder.startObject().endObject(); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetSslCertificatesResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetSslCertificatesResponse.java new file mode 100644 index 0000000000000..80f016b3ae1bf --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetSslCertificatesResponse.java @@ -0,0 +1,68 @@ +/* + * 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.security.support.CertificateInfo; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParserUtils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Response object when retrieving the X.509 certificates that are used to encrypt communications in an Elasticsearch cluster. + * Returns a list of {@link CertificateInfo} objects describing each of the certificates. + */ +public final class GetSslCertificatesResponse { + + private final List certificates; + + public GetSslCertificatesResponse(List certificates) { + this.certificates = certificates; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final GetSslCertificatesResponse that = (GetSslCertificatesResponse) o; + return Objects.equals(this.certificates, that.certificates); + } + + @Override + public int hashCode() { + return Objects.hash(certificates); + } + + public static GetSslCertificatesResponse fromXContent(XContentParser parser) throws IOException { + List certificates = new ArrayList<>(); + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.nextToken(), parser::getTokenLocation); + while (parser.nextToken() != XContentParser.Token.END_ARRAY) { + certificates.add(CertificateInfo.PARSER.parse(parser, null)); + } + return new GetSslCertificatesResponse(certificates); + } + + public List getCertificates() { + return certificates; + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/CertificateInfo.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/CertificateInfo.java new file mode 100644 index 0000000000000..28fd1c61c0d5c --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/CertificateInfo.java @@ -0,0 +1,133 @@ +/* + * 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.support; + +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.Objects; + +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; + +/** + * Simple model of an X.509 certificate + */ +public final class CertificateInfo { + public static final ParseField PATH = new ParseField("path"); + public static final ParseField FORMAT = new ParseField("format"); + public static final ParseField ALIAS = new ParseField("alias"); + public static final ParseField SUBJECT_DN = new ParseField("subject_dn"); + public static final ParseField SERIAL_NUMBER = new ParseField("serial_number"); + public static final ParseField HAS_PRIVATE_KEY = new ParseField("has_private_key"); + public static final ParseField EXPIRY = new ParseField("expiry"); + + private final String path; + private final String format; + private final String alias; + private final String subjectDn; + private final String serialNumber; + private final boolean hasPrivateKey; + private final String expiry; + + public CertificateInfo(String path, String format, @Nullable String alias, String subjectDn, String serialNumber, boolean hasPrivateKey, + String expiry) { + this.path = path; + this.format = format; + this.alias = alias; + this.subjectDn = subjectDn; + this.serialNumber = serialNumber; + this.hasPrivateKey = hasPrivateKey; + this.expiry = expiry; + } + + public String getPath() { + return path; + } + + public String getFormat() { + return format; + } + + public String getAlias() { + return alias; + } + + public String getSubjectDn() { + return subjectDn; + } + + public String getSerialNumber() { + return serialNumber; + } + + public boolean isHasPrivateKey() { + return hasPrivateKey; + } + + public String getExpiry() { + return expiry; + } + + @SuppressWarnings("unchecked") + public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("certificate_info", + true, args -> new CertificateInfo((String) args[0], (String) args[1], (String) args[2], (String) args[3], (String) args[4], + (boolean) args[5], (String) args[6])); + + static { + PARSER.declareString(constructorArg(), PATH); + PARSER.declareString(constructorArg(), FORMAT); + PARSER.declareStringOrNull(constructorArg(), ALIAS); + PARSER.declareString(constructorArg(), SUBJECT_DN); + PARSER.declareString(constructorArg(), SERIAL_NUMBER); + PARSER.declareBoolean(constructorArg(), HAS_PRIVATE_KEY); + PARSER.declareString(constructorArg(), EXPIRY); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + + final CertificateInfo that = (CertificateInfo) other; + return this.path.equals(that.path) + && this.format.equals(that.format) + && this.hasPrivateKey == that.hasPrivateKey + && Objects.equals(this.alias, that.alias) + && this.serialNumber.equals(that.serialNumber) + && this.subjectDn.equals(that.subjectDn) + && this.expiry.equals(that.expiry); + } + + @Override + public int hashCode() { + return Objects.hash(path, format, alias, subjectDn, serialNumber, hasPrivateKey, expiry); + } + + public static CertificateInfo fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java index acdfc50b5a13a..fda7ecdd6d6a2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RestHighLevelClientTests.java @@ -721,10 +721,16 @@ public void testApiNamingConventions() throws Exception { methods.containsKey(apiName.substring(0, apiName.length() - 6))); assertThat(method.getReturnType(), equalTo(Void.TYPE)); assertEquals(0, method.getExceptionTypes().length); - assertEquals(3, method.getParameterTypes().length); - assertThat(method.getParameterTypes()[0].getSimpleName(), endsWith("Request")); - assertThat(method.getParameterTypes()[1], equalTo(RequestOptions.class)); - assertThat(method.getParameterTypes()[2], equalTo(ActionListener.class)); + if (apiName.equals("security.get_ssl_certificates_async")) { + assertEquals(2, method.getParameterTypes().length); + assertThat(method.getParameterTypes()[0], equalTo(RequestOptions.class)); + assertThat(method.getParameterTypes()[1], equalTo(ActionListener.class)); + } else { + assertEquals(3, method.getParameterTypes().length); + assertThat(method.getParameterTypes()[0].getSimpleName(), endsWith("Request")); + assertThat(method.getParameterTypes()[1], equalTo(RequestOptions.class)); + assertThat(method.getParameterTypes()[2], equalTo(ActionListener.class)); + } } else { //A few methods return a boolean rather than a response object if (apiName.equals("ping") || apiName.contains("exist")) { @@ -735,7 +741,7 @@ public void testApiNamingConventions() throws Exception { assertEquals(1, method.getExceptionTypes().length); //a few methods don't accept a request object as argument - if (apiName.equals("ping") || apiName.equals("info")) { + if (apiName.equals("ping") || apiName.equals("info") || apiName.equals("security.get_ssl_certificates")) { assertEquals(1, method.getParameterTypes().length); assertThat(method.getParameterTypes()[0], equalTo(RequestOptions.class)); } else { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index 778ec7b5707cd..f80cbb0e67fa3 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -27,12 +27,17 @@ import org.elasticsearch.client.security.ChangePasswordRequest; import org.elasticsearch.client.security.DisableUserRequest; import org.elasticsearch.client.security.EnableUserRequest; +import org.elasticsearch.client.security.GetSslCertificatesResponse; 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 org.elasticsearch.client.security.support.CertificateInfo; +import org.hamcrest.Matchers; import java.util.Collections; +import java.util.Iterator; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -175,6 +180,87 @@ public void onFailure(Exception e) { } } + public void testGetSslCertificates() throws Exception { + RestHighLevelClient client = highLevelClient(); + { + //tag::get-certificates-execute + GetSslCertificatesResponse response = client.security().getSslCertificates(RequestOptions.DEFAULT); + //end::get-certificates-execute + + assertNotNull(response); + + //tag::get-certificates-response + List certificates = response.getCertificates(); // <1> + //end::get-certificates-response + + assertThat(certificates.size(), Matchers.equalTo(9)); + final Iterator it = certificates.iterator(); + CertificateInfo c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=testnode-client-profile")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=Elasticsearch Test Node, OU=elasticsearch, O=org")); + assertThat(c.getPath(), Matchers.equalTo("testnode.crt")); + assertThat(c.getFormat(), Matchers.equalTo("PEM")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=OpenLDAP, OU=Elasticsearch, O=Elastic, L=Mountain View, ST=CA, C=US")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=Elasticsearch Test Node, OU=elasticsearch, O=org")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=Elasticsearch Test Client, OU=elasticsearch, O=org")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=ad-ELASTICSEARCHAD-CA, DC=ad, DC=test, DC=elasticsearch, DC=com")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=Elasticsearch Test Node")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=samba4")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + c = it.next(); + assertThat(c.getSubjectDn(), Matchers.equalTo("CN=Elasticsearch Test Node")); + assertThat(c.getPath(), Matchers.equalTo("testnode.jks")); + assertThat(c.getFormat(), Matchers.equalTo("jks")); + } + + { + // tag::get-certificates-execute-listener + ActionListener listener = new ActionListener() { + @Override + public void onResponse(GetSslCertificatesResponse getSslCertificatesResponse) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + + // end::get-certificates-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::get-certificates-execute-async + client.security().getSslCertificatesAsync(RequestOptions.DEFAULT, listener); // <1> + // end::end-certificates-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + } + public void testChangePassword() throws Exception { RestHighLevelClient client = highLevelClient(); char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; diff --git a/client/rest-high-level/testnode.crt b/client/rest-high-level/testnode.crt new file mode 100644 index 0000000000000..08c160bcea5ff --- /dev/null +++ b/client/rest-high-level/testnode.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID0zCCArugAwIBAgIJALi5bDfjMszLMA0GCSqGSIb3DQEBCwUAMEgxDDAKBgNV +BAoTA29yZzEWMBQGA1UECxMNZWxhc3RpY3NlYXJjaDEgMB4GA1UEAxMXRWxhc3Rp +Y3NlYXJjaCBUZXN0IE5vZGUwHhcNMTUwOTIzMTg1MjU3WhcNMTkwOTIyMTg1MjU3 +WjBIMQwwCgYDVQQKEwNvcmcxFjAUBgNVBAsTDWVsYXN0aWNzZWFyY2gxIDAeBgNV +BAMTF0VsYXN0aWNzZWFyY2ggVGVzdCBOb2RlMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA3rGZ1QbsW0+MuyrSLmMfDFKtLBkIFW8V0gRuurFg1PUKKNR1 +Mq2tMVwjjYETAU/UY0iKZOzjgvYPKhDTYBTte/WHR1ZK4CYVv7TQX/gtFQG/ge/c +7u0sLch9p7fbd+/HZiLS/rBEZDIohvgUvzvnA8+OIYnw4kuxKo/5iboAIS41klMg +/lATm8V71LMY68inht71/ZkQoAHKgcR9z4yNYvQ1WqKG8DG8KROXltll3sTrKbl5 +zJhn660es/1ZnR6nvwt6xnSTl/mNHMjkfv1bs4rJ/py3qPxicdoSIn/KyojUcgHV +F38fuAy2CQTdjVG5fWj9iz+mQvLm3+qsIYQdFwIDAQABo4G/MIG8MAkGA1UdEwQC +MAAwHQYDVR0OBBYEFEMMWLWQi/g83PzlHYqAVnty5L7HMIGPBgNVHREEgYcwgYSC +CWxvY2FsaG9zdIIVbG9jYWxob3N0LmxvY2FsZG9tYWluggpsb2NhbGhvc3Q0ghds +b2NhbGhvc3Q0LmxvY2FsZG9tYWluNIIKbG9jYWxob3N0NoIXbG9jYWxob3N0Ni5s +b2NhbGRvbWFpbjaHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQEL +BQADggEBAMjGGXT8Nt1tbl2GkiKtmiuGE2Ej66YuZ37WSJViaRNDVHLlg87TCcHe +k2rdO+6sFqQbbzEfwQ05T7xGmVu7tm54HwKMRugoQ3wct0bQC5wEWYN+oMDvSyO6 +M28mZwWb4VtR2IRyWP+ve5DHwTM9mxWa6rBlGzsQqH6YkJpZojzqk/mQTug+Y8aE +mVoqRIPMHq9ob+S9qd5lp09+MtYpwPfTPx/NN+xMEooXWW/ARfpGhWPkg/FuCu4z +1tFmCqHgNcWirzMm3dQpF78muE9ng6OB2MXQwL4VgnVkxmlZNHbkR2v/t8MyZJxC +y4g6cTMM3S/UMt5/+aIB2JAuMKyuD+A= +-----END CERTIFICATE----- diff --git a/client/rest-high-level/testnode.jks b/client/rest-high-level/testnode.jks new file mode 100644 index 0000000000000..ebe6146124e8f Binary files /dev/null and b/client/rest-high-level/testnode.jks differ diff --git a/docs/java-rest/high-level/security/get-certificates.asciidoc b/docs/java-rest/high-level/security/get-certificates.asciidoc new file mode 100644 index 0000000000000..6820b1564fb8e --- /dev/null +++ b/docs/java-rest/high-level/security/get-certificates.asciidoc @@ -0,0 +1,53 @@ +[[java-rest-high-security-get-certificates]] +=== SSL Certificate API + +[[java-rest-high-security-get-certificates-execution]] +==== Execution + +The X.509 Certificates that are used to encrypt communications in an +Elasticsearch cluster using the `security().getSslCertificates()` method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[get-certificates-execute] +-------------------------------------------------- + +[[java-rest-high-security-get-certificates-response]] +==== Response + +The returned `GetSslCertificatesResponse` contains a single field, `certificates`. +This field, accessed with `getCertificates` returns a List of `CertificateInfo` +objects containing the information for all the certificates used. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[get-certificates-response] +-------------------------------------------------- +<1> `certificates` is a List of `CertificateInfo` + +[[java-rest-high-security-get-certificates-execute-async]] +==== Asynchronous Execution + +This request can be executed asynchronously using the `security().getSslCertificatesAsync()` +method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[get-certificates-execute-async] +-------------------------------------------------- +<1> 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 `GetSslCertificatesResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[get-certificates-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. diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 3bc5905a46fe5..2cec49f8bcfd7 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -298,11 +298,13 @@ The Java High Level REST Client supports the following Security APIs: * <> * <> * <> +* <> include::security/put-user.asciidoc[] include::security/enable-user.asciidoc[] include::security/disable-user.asciidoc[] include::security/change-password.asciidoc[] +include::security/get-certificates.asciidoc[] == Watcher APIs