Help Center/ Cloud Search Service/ Best Practices/ Cluster Access/ Accessing a Cluster Using Java/ Accessing a Cluster Through the Rest Low Level Client
Updated on 2023-03-29 GMT+08:00

Accessing a Cluster Through the Rest Low Level Client

The high-level client is encapsulated based on the low-level client. If the method calls (such as .search and .bulk) in the high-level client cannot meet the requirements or has compatibility issues, you can use the low-level client. You can even use HighLevelClient.getLowLevelClient() to directly obtain a low-level client. A low-level client allows you to define the request structure, which is more flexible and supports all the request formats of Elasticsearch, such as GET, POST, DELETE, and HEAD.

This section describes how to use the Rest Low Level Client to access the CSS cluster. The methods are as follows. For each method, you can directly create a REST low-level client, or create a high-level client and then invoke getLowLevelClient() to obtain a low-level client.

Precautions

You are advised to use the Rest Low Level Client version that matches the Elasticsearch version. For example, use Rest Low Level Client 7.6.2 to access the Elasticsearch cluster 7.6.2.

Prerequisites

  • The CSS cluster is available.
  • Ensure that the server running Java can communicate with the CSS cluster.
  • Install JDK 1.8 on the server. You can download JDK 1.8 from: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
  • Declare the Apache version in Maven mode. The following code uses version 7.6.2 as an example.

    7.6.2 indicates the version of the Elasticsearch Java client.

    <dependency>
    	<groupId>org.elasticsearch.client</groupId>
    	<artifactId>elasticsearch-rest-client</artifactId>
    	<version>7.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.6.2</version>
    </dependency>

Connecting to a Non-Security Cluster Through the Rest Low Level Client

  • Method 1: Directly create a Rest Low Level Client.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import org.apache.http.HttpHost;
    import org.elasticsearch.client.Request;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    public class Main {
    
        public static void main(String[] args) throws IOException {
            List<String> host = Arrays.asList("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx");
            RestClientBuilder builder = RestClient.builder(constructHttpHosts(host, 9200, "http"));
            /**
             * Create a Rest Low Level Client.
             */
            RestClient lowLevelClient = builder.build();
            /**
             * Check whether the test index exists. If the index exists, 200 is returned. If the index does not exist, 404 is returned.
             */
            Request request = new Request("HEAD", "/test");
            Response response = lowLevelClient.performRequest(request);
            System.out.println(response.getStatusLine().getStatusCode());
            lowLevelClient.close();
        }
    
        /**
         * Use the constructHttpHosts function to convert the node IP address list of the host cluster.
         */
        public static HttpHost[] constructHttpHosts(List<String> host, int port, String protocol) {
            return host.stream().map(p -> new HttpHost(p, port, protocol)).toArray(HttpHost[]::new);
        }
    }
    
  • Method 2: Create a high-level client and then call getLowLevelClient() to obtain a low-level client.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    import org.apache.http.HttpHost;
    import org.elasticsearch.client.Request;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.client.RestHighLevelClient;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    public class Main {
    
        public static void main(String[] args) throws IOException {
            List<String> host = Arrays.asList("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx");
            RestClientBuilder builder = RestClient.builder(constructHttpHosts(host, 9200, "http"));
            final RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
            /**
             * Create a high-level client and then call getLowLevelClient() to obtain a low-level client. The code differs from the client creation code only in the following line:
             */
            final RestClient lowLevelClient = restHighLevelClient.getLowLevelClient();
            /**
             * Check whether the test index exists. If the index exists, 200 is returned. If the index does not exist, 404 is returned.
             */
            Request request = new Request("HEAD", "/test");
            Response response = lowLevelClient.performRequest(request);
            System.out.println(response.getStatusLine().getStatusCode());
            lowLevelClient.close();
        }
    
        /**
         * Use the constructHttpHosts function to convert the node IP address list of the host cluster.
         */
        public static HttpHost[] constructHttpHosts(List<String> host, int port, String protocol) {
            return host.stream().map(p -> new HttpHost(p, port, protocol)).toArray(HttpHost[]::new);
        }
    }
    

host indicates the IP address list of each node in the cluster. If there are multiple IP addresses, separate them with commas (,). test indicates the index name to be queried.

Connecting to a Security Cluster Through Rest Low Level Client (Without Security Certificates)

  • Method 1: Directly create a Rest Low Level Client.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    import org.apache.http.HttpHost;
    import org.apache.http.HttpResponse;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.CredentialsProvider;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
    import org.apache.http.protocol.HttpContext;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.elasticsearch.client.Request;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.common.Nullable;
    
    import java.io.IOException;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    import java.util.concurrent.TimeUnit;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;
    
    public class Main {
    
        /**
         * Create a class for the client. Define the create function.
         */
        public static RestClient create(List<String> host, int port, String protocol, int connectTimeout, int connectionRequestTimeout, int socketTimeout,  String username, String password) throws IOException {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            SSLContext sc = null;
            try {
                sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new SecureRandom());
            } catch (KeyManagementException | NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sc, new NullHostNameVerifier());
            SecuredHttpClientConfigCallback httpClientConfigCallback = new SecuredHttpClientConfigCallback(sessionStrategy,
                credentialsProvider);
    
            RestClientBuilder builder = RestClient.builder(constructHttpHosts(host, port, protocol))
                .setRequestConfigCallback(requestConfig -> requestConfig.setConnectTimeout(connectTimeout)
                    .setConnectionRequestTimeout(connectionRequestTimeout)
                    .setSocketTimeout(socketTimeout))
                .setHttpClientConfigCallback(httpClientConfigCallback);
            final RestClient client = builder.build();
            logger.info("es rest client build success {} ", client);
            return client;
        }
    
        /**
         * Use the constructHttpHosts function to convert the node IP address list of the host cluster.
         */
        public static HttpHost[] constructHttpHosts(List<String> host, int port, String protocol) {
            return host.stream().map(p -> new HttpHost(p, port, protocol)).toArray(HttpHost[]::new);
        }
    
        /**
         * Configure trustAllCerts to ignore the certificate configuration.
         */
        public static TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }
        };
    
        /**
    * The CustomConnectionKeepAliveStrategy function is used to set the connection keepalive time when there are a large number of short connections or when the number of data requests is small.
         */
        public static class CustomConnectionKeepAliveStrategy extends DefaultConnectionKeepAliveStrategy {
            public static final CustomConnectionKeepAliveStrategy INSTANCE = new CustomConnectionKeepAliveStrategy();
    
            private CustomConnectionKeepAliveStrategy() {
                super();
            }
    
            /**
             * Maximum keep alive time (minutes)
             * The default value is 10 minutes. You can set it based on the number of TCP connections in TIME_WAIT state. If there are too many TCP connections, you can increase the value.
             */
            private final long MAX_KEEP_ALIVE_MINUTES = 10;
    
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                long keepAliveDuration = super.getKeepAliveDuration(response, context);
                // <0 indicates that the keepalive period is unlimited.
                // Change the period from unlimited to a default period.
                if (keepAliveDuration < 0) {
                    return TimeUnit.MINUTES.toMillis(MAX_KEEP_ALIVE_MINUTES);
                }
                return keepAliveDuration;
            }
        }
    
        private static final Logger logger = LogManager.getLogger(Main.class);
    
        static class SecuredHttpClientConfigCallback implements RestClientBuilder.HttpClientConfigCallback {
            @Nullable
            private final CredentialsProvider credentialsProvider;
            /**
             * The {@link SSLIOSessionStrategy} for all requests to enable SSL / TLS encryption.
             */
            private final SSLIOSessionStrategy sslStrategy;
            /**
             * Create a new {@link SecuredHttpClientConfigCallback}.
             *
             * @param credentialsProvider The credential provider, if a username/password have been supplied
             * @param sslStrategy         The SSL strategy, if SSL / TLS have been supplied
             * @throws NullPointerException if {@code sslStrategy} is {@code null}
             */
            SecuredHttpClientConfigCallback(final SSLIOSessionStrategy sslStrategy,
                @Nullable final CredentialsProvider credentialsProvider) {
                this.sslStrategy = Objects.requireNonNull(sslStrategy);
                this.credentialsProvider = credentialsProvider;
            }
            /**
             * Get the {@link CredentialsProvider} that will be added to the HTTP client.
             *
             * @return Can be {@code null}.
             */
            @Nullable
            CredentialsProvider getCredentialsProvider() {
                return credentialsProvider;
            }
            /**
             * Get the {@link SSLIOSessionStrategy} that will be added to the HTTP client.
             *
             * @return Never {@code null}.
             */
            SSLIOSessionStrategy getSSLStrategy() {
                return sslStrategy;
            }
            /**
             * Sets the {@linkplain HttpAsyncClientBuilder#setDefaultCredentialsProvider(CredentialsProvider) credential provider},
             *
             * @param httpClientBuilder The client to configure.
             * @return Always {@code httpClientBuilder}.
             */
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder httpClientBuilder) {
                // enable SSL / TLS
                httpClientBuilder.setSSLStrategy(sslStrategy);
                // enable user authentication
                if (credentialsProvider != null) {
                    httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
                return httpClientBuilder;
            }
        }
    
        public static class NullHostNameVerifier implements HostnameVerifier {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        }
    
        /**
         * The following is an example of the main function. Call the create function to create a Rest Low Level Client and check whether the test index exists.
         */
        public static void main(String[] args) throws IOException {
            RestClient lowLevelClient = create(Arrays.asList("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx"), 9200, "http", 1000, 1000, 1000, "username", "password");
            Request request = new Request("HEAD", "/test");
            Response response = lowLevelClient.performRequest(request);
            System.out.println(response.getStatusLine().getStatusCode());
            lowLevelClient.close();
        }
    }
    
  • Method 2: Create a high-level client and then call getLowLevelClient() to obtain a low-level client.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    import org.apache.http.HttpHost;
    import org.apache.http.HttpResponse;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.CredentialsProvider;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
    import org.apache.http.protocol.HttpContext;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.elasticsearch.client.Request;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.common.Nullable;
    
    import java.io.IOException;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    import java.util.concurrent.TimeUnit;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;
    
    import org.elasticsearch.client.RestHighLevelClient;
    
    public class Main13 {
    
        /**
         * Create a class for the client. Define the create function.
         */
        public static RestHighLevelClient create(List<String> host, int port, String protocol, int connectTimeout, int connectionRequestTimeout, int socketTimeout,  String username, String password) throws IOException {
    
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            SSLContext sc = null;
            try {
                sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new SecureRandom());
            } catch (KeyManagementException | NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sc, new NullHostNameVerifier());
            SecuredHttpClientConfigCallback httpClientConfigCallback = new SecuredHttpClientConfigCallback(sessionStrategy,
                credentialsProvider);
    
            RestClientBuilder builder = RestClient.builder(constructHttpHosts(host, port, protocol))
                .setRequestConfigCallback(requestConfig -> requestConfig.setConnectTimeout(connectTimeout)
                    .setConnectionRequestTimeout(connectionRequestTimeout)
                    .setSocketTimeout(socketTimeout))
                .setHttpClientConfigCallback(httpClientConfigCallback);
            final RestHighLevelClient client = new RestHighLevelClient(builder);
            logger.info("es rest client build success {} ", client);
            return client;
        }
    
        /**
         * Use the constructHttpHosts function to convert the node IP address list of the host cluster.
         */
        public static HttpHost[] constructHttpHosts(List<String> host, int port, String protocol) {
            return host.stream().map(p -> new HttpHost(p, port, protocol)).toArray(HttpHost[]::new);
        }
    
        /**
         * Configure trustAllCerts to ignore the certificate configuration.
         */
        public static TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }
        };
    
        /**
    * The CustomConnectionKeepAliveStrategy function is used to set the connection keepalive time when there are a large number of short connections or when the number of data requests is small.
         */
        public static class CustomConnectionKeepAliveStrategy extends DefaultConnectionKeepAliveStrategy {
            public static final CustomConnectionKeepAliveStrategy INSTANCE = new CustomConnectionKeepAliveStrategy();
    
            private CustomConnectionKeepAliveStrategy() {
                super();
            }
    
            /**
             * Maximum keep alive time (minutes)
             * The default value is 10 minutes. You can set it based on the number of TCP connections in TIME_WAIT state. If there are too many TCP connections, you can increase the value.
             */
            private final long MAX_KEEP_ALIVE_MINUTES = 10;
    
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                long keepAliveDuration = super.getKeepAliveDuration(response, context);
                // <0 indicates that the keepalive period is unlimited.
                // Change the period from unlimited to a default period.
                if (keepAliveDuration < 0) {
                    return TimeUnit.MINUTES.toMillis(MAX_KEEP_ALIVE_MINUTES);
                }
                return keepAliveDuration;
            }
        }
    
        private static final Logger logger = LogManager.getLogger(Main.class);
    
        static class SecuredHttpClientConfigCallback implements RestClientBuilder.HttpClientConfigCallback {
            @Nullable
            private final CredentialsProvider credentialsProvider;
            /**
             * The {@link SSLIOSessionStrategy} for all requests to enable SSL / TLS encryption.
             */
            private final SSLIOSessionStrategy sslStrategy;
            /**
             * Create a new {@link SecuredHttpClientConfigCallback}.
             *
             * @param credentialsProvider The credential provider, if a username/password have been supplied
             * @param sslStrategy         The SSL strategy, if SSL / TLS have been supplied
             * @throws NullPointerException if {@code sslStrategy} is {@code null}
             */
            SecuredHttpClientConfigCallback(final SSLIOSessionStrategy sslStrategy,
                @Nullable final CredentialsProvider credentialsProvider) {
                this.sslStrategy = Objects.requireNonNull(sslStrategy);
                this.credentialsProvider = credentialsProvider;
            }
            /**
             * Get the {@link CredentialsProvider} that will be added to the HTTP client.
             *
             * @return Can be {@code null}.
             */
            @Nullable
            CredentialsProvider getCredentialsProvider() {
                return credentialsProvider;
            }
            /**
             * Get the {@link SSLIOSessionStrategy} that will be added to the HTTP client.
             *
             * @return Never {@code null}.
             */
            SSLIOSessionStrategy getSSLStrategy() {
                return sslStrategy;
            }
            /**
             * Sets the {@linkplain HttpAsyncClientBuilder#setDefaultCredentialsProvider(CredentialsProvider) credential provider},
             *
             * @param httpClientBuilder The client to configure.
             * @return Always {@code httpClientBuilder}.
             */
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder httpClientBuilder) {
                // enable SSL / TLS
                httpClientBuilder.setSSLStrategy(sslStrategy);
                // enable user authentication
                if (credentialsProvider != null) {
                    httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
                return httpClientBuilder;
            }
        }
    
        public static class NullHostNameVerifier implements HostnameVerifier {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        }
    
        /**
    * The following is an example of the main function. Call the create function to create a high-level client, call the getLowLevelClient() function to obtain a low-level client, and check whether the test index exists.
         */
        public static void main(String[] args) throws IOException {
            RestHighLevelClient client = create(Arrays.asList("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx"), 9200, "http", 1000, 1000, 1000, "username", "password");
            RestClient lowLevelClient = client.getLowLevelClient();
            Request request = new Request("HEAD", "test");
            Response response = lowLevelClient.performRequest(request);
            System.out.println(response.getStatusLine().getStatusCode());
            lowLevelClient.close();
        }
    }
    
Table 1 Variables

Parameter

Description

host

List of the IP addresses of Elasticsearch nodes (or independent Client node). Multiple IP addresses are separated using commas (,).

port

Access port of the Elasticsearch cluster. The default value is 9200.

protocol

Connection protocol, which can be http or https.

connectTimeout

Socket connection timeout period.

connectionRequestTimeout

Timeout period of a socket connection request.

socketTimeout

Timeout period of a socket request.

username

Username for accessing the cluster.

password

Password of the user.

Connecting to a Security Cluster Through Rest Low Level Client (With Security Certificates)

  • Method 1: Directly create a Rest Low Level Client.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    import org.apache.http.HttpHost;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.CredentialsProvider;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.elasticsearch.client.Request;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.common.Nullable;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    
    import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    
    public class Main13 {
    
        private static final Logger logger = LogManager.getLogger(Main.class);
    
        /**
         * Create a class for the client. Define the create function.
         */
        public static RestClient create(List<String> host, int port, String protocol, int connectTimeout, int connectionRequestTimeout, int socketTimeout, String username, String password, String cerFilePath, String cerPassword) throws IOException {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            SSLContext sc = null;
            try {
                TrustManager[] tm = {new MyX509TrustManager(cerFilePath, cerPassword)};
                sc = SSLContext.getInstance("SSL", "SunJSSE");
                //You can also use SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
                sc.init(null, tm, new SecureRandom());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sc, new NoopHostnameVerifier());
            SecuredHttpClientConfigCallback httpClientConfigCallback = new SecuredHttpClientConfigCallback(sessionStrategy,
                credentialsProvider);
    
            RestClientBuilder builder = RestClient.builder(constructHttpHosts(host, port, protocol))
                .setRequestConfigCallback(requestConfig -> requestConfig.setConnectTimeout(connectTimeout)
                    .setConnectionRequestTimeout(connectionRequestTimeout)
                    .setSocketTimeout(socketTimeout))
                .setHttpClientConfigCallback(httpClientConfigCallback);
            final RestClient client = builder.build();
            logger.info("es rest client build success {} ", client);
            return client;
        }
    
        /**
         * Use the constructHttpHosts function to convert the node IP address list of the host cluster.
         */
        public static HttpHost[] constructHttpHosts(List<String> host, int port, String protocol) {
            return host.stream().map(p -> new HttpHost(p, port, protocol)).toArray(HttpHost[]::new);}
    
        static class SecuredHttpClientConfigCallback implements RestClientBuilder.HttpClientConfigCallback {
            @Nullable
            private final CredentialsProvider credentialsProvider;
    
            private final SSLIOSessionStrategy sslStrategy;
    
            SecuredHttpClientConfigCallback(final SSLIOSessionStrategy sslStrategy,
                @Nullable final CredentialsProvider credentialsProvider) {
                this.sslStrategy = Objects.requireNonNull(sslStrategy);
                this.credentialsProvider = credentialsProvider;
            }
    
            @Nullable
            CredentialsProvider getCredentialsProvider() {
                return credentialsProvider;
            }
    
            SSLIOSessionStrategy getSSLStrategy() {
                return sslStrategy;
            }
    
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder httpClientBuilder) {
                httpClientBuilder.setSSLStrategy(sslStrategy);
                if (credentialsProvider != null) {
                    httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
                return httpClientBuilder;
            }}
    
        public static class MyX509TrustManager implements X509TrustManager {
            X509TrustManager sunJSSEX509TrustManager;
    
            MyX509TrustManager(String cerFilePath, String cerPassword) throws Exception {
                File file = new File(cerFilePath);
                if (!file.isFile()) {
                    throw new Exception("Wrong Certification Path");
                }
                System.out.println("Loading KeyStore " + file + "...");
                InputStream in = new FileInputStream(file);
                KeyStore ks = KeyStore.getInstance("JKS");
                ks.load(in, cerPassword.toCharArray());
                TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
                tmf.init(ks);
                TrustManager[] tms = tmf.getTrustManagers();
                for (TrustManager tm : tms) {
                    if (tm instanceof X509TrustManager) {
                        sunJSSEX509TrustManager = (X509TrustManager) tm;
                        return;
                    }
                }
                throw new Exception("Couldn't initialize");
            }
    
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    
            }
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }
    
        /**
         * The following is an example of the main function. Call the create function to create a Rest Low Level Client and check whether the test index exists.
         */
        public static void main(String[] args) throws IOException {
            RestClient lowLevelClient = create(Arrays.asList("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx"), 9200, "https", 1000, 1000, 1000, "username", "password", "cerFilePath", "cerPassword");
            Request request = new Request("HEAD", "test");
            Response response = lowLevelClient.performRequest(request);
            System.out.println(response.getStatusLine().getStatusCode());
            lowLevelClient.close();
        }
    }
    
  • Method 2: Create a high-level client and then call getLowLevelClient() to obtain a low-level client.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    import org.apache.http.HttpHost;
    import org.apache.http.auth.AuthScope;
    import org.apache.http.auth.UsernamePasswordCredentials;
    import org.apache.http.client.CredentialsProvider;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
    import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
    import org.elasticsearch.client.Request;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.Response;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.Nullable;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    
    import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    
    public class Main {
    
        private static final Logger logger = LogManager.getLogger(Main.class);
    
        /**
         * Create a class for the client. Define the create function.
         */
        public static RestHighLevelClient create(List<String> host, int port, String protocol, int connectTimeout, int connectionRequestTimeout, int socketTimeout, String username, String password, String cerFilePath, String cerPassword) throws IOException {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            SSLContext sc = null;
            try {
                TrustManager[] tm = {new MyX509TrustManager(cerFilePath, cerPassword)};
                sc = SSLContext.getInstance("SSL", "SunJSSE");
                //You can also use SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
                sc.init(null, tm, new SecureRandom());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sc, new NoopHostnameVerifier());
            SecuredHttpClientConfigCallback httpClientConfigCallback = new SecuredHttpClientConfigCallback(sessionStrategy,
                credentialsProvider);
    
            RestClientBuilder builder = RestClient.builder(constructHttpHosts(host, port, protocol))
                .setRequestConfigCallback(requestConfig -> requestConfig.setConnectTimeout(connectTimeout)
                    .setConnectionRequestTimeout(connectionRequestTimeout)
                    .setSocketTimeout(socketTimeout))
                .setHttpClientConfigCallback(httpClientConfigCallback);
            final RestHighLevelClient client = new RestHighLevelClient(builder);
            logger.info("es rest client build success {} ", client);
    
            ClusterHealthRequest request = new ClusterHealthRequest();
            ClusterHealthResponse response = client.cluster().health(request, RequestOptions.DEFAULT);
            logger.info("es rest client health response {} ", response);
            return client;
        }
    
        /**
         * Use the constructHttpHosts function to convert the node IP address list of the host cluster.
         */
        public static HttpHost[] constructHttpHosts(List<String> host, int port, String protocol) {
            return host.stream().map(p -> new HttpHost(p, port, protocol)).toArray(HttpHost[]::new);}
    
        static class SecuredHttpClientConfigCallback implements RestClientBuilder.HttpClientConfigCallback {
            @Nullable
            private final CredentialsProvider credentialsProvider;
    
            private final SSLIOSessionStrategy sslStrategy;
    
            SecuredHttpClientConfigCallback(final SSLIOSessionStrategy sslStrategy,
                @Nullable final CredentialsProvider credentialsProvider) {
                this.sslStrategy = Objects.requireNonNull(sslStrategy);
                this.credentialsProvider = credentialsProvider;
            }
    
            @Nullable
            CredentialsProvider getCredentialsProvider() {
                return credentialsProvider;
            }
    
            SSLIOSessionStrategy getSSLStrategy() {
                return sslStrategy;
            }
    
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(final HttpAsyncClientBuilder httpClientBuilder) {
                httpClientBuilder.setSSLStrategy(sslStrategy);
                if (credentialsProvider != null) {
                    httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
                return httpClientBuilder;
            }}
    
        public static class MyX509TrustManager implements X509TrustManager {
            X509TrustManager sunJSSEX509TrustManager;
    
            MyX509TrustManager(String cerFilePath, String cerPassword) throws Exception {
                File file = new File(cerFilePath);
                if (!file.isFile()) {
                    throw new Exception("Wrong Certification Path");
                }
                System.out.println("Loading KeyStore " + file + "...");
                InputStream in = new FileInputStream(file);
                KeyStore ks = KeyStore.getInstance("JKS");
                ks.load(in, cerPassword.toCharArray());
                TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
                tmf.init(ks);
                TrustManager[] tms = tmf.getTrustManagers();
                for (TrustManager tm : tms) {
                    if (tm instanceof X509TrustManager) {
                        sunJSSEX509TrustManager = (X509TrustManager) tm;
                        return;
                    }
                }
                throw new Exception("Couldn't initialize");
            }
    
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    
            }
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }
    
        /**
    * The following is an example of the main function. Call the create function to create a high-level client, call the getLowLevelClient() function to obtain a low-level client, and check whether the test index exists.
         */
        public static void main(String[] args) throws IOException {
            RestHighLevelClient client = create(Arrays.asList("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx"), 9200, "https", 1000, 1000, 1000, "username", "password", "cerFilePath", "cerPassword");
            RestClient lowLevelClient = client.getLowLevelClient();
            Request request = new Request("HEAD", "test");
            Response response = lowLevelClient.performRequest(request);
            System.out.println(response.getStatusLine().getStatusCode());
            lowLevelClient.close();
        }
    }
    
Table 2 Function parameters

Name

Description

host

List of the IP addresses of Elasticsearch nodes (or independent Client node). Multiple IP addresses are separated using commas (,).

port

Access port of the Elasticsearch cluster. The default value is 9200.

protocol

Connection protocol. Set this parameter to https.

connectTimeout

Socket connection timeout period.

connectionRequestTimeout

Timeout period of a socket connection request.

socketTimeout

Timeout period of a socket request.

username

Username for accessing the cluster.

password

Password of the user.

cerFilePath

Certificate path.

cerPassword

Certificate password.