private RestHighLevelClient createEsClient(ApimanEsClientOptionsParser opts,
        Map<String, EsIndexProperties> esIndexes) {

        String protocol = opts.getProtocol();
        String host = opts.getHost();
        int port = opts.getPort();
        String indexNamePrefix = opts.getIndexNamePrefix();
        int timeout = opts.getTimeout();

        LOGGER.info("Building an Elasticsearch client for {0}://{1}:{2} for index prefix {3}",
            protocol, host, port, indexNamePrefix);

        synchronized (clients) {
            String clientKey = "es:" + host + ':' + port + '/' + indexNamePrefix;

            RestHighLevelClient client;

            if (clients.containsKey(clientKey)) {
                client = clients.get(clientKey);
                LOGGER.info("Use cached Elasticsearch client with client key " + clientKey);
            } else {
                RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(host, port, protocol))
                    .setRequestConfigCallback(builder -> builder.setConnectTimeout(timeout)
                    .setSocketTimeout(timeout));

                HttpAsyncClientBuilder asyncClientBuilder = HttpAsyncClientBuilder.create();

                opts.getUsernameAndPassword().ifPresent(creds -> {
                    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

                    credentialsProvider.setCredentials(
                        AuthScope.ANY,
                        new UsernamePasswordCredentials(creds.getUsername(), creds.getPasswordAsString())
                    );

                    asyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                });

                if ("https".equalsIgnoreCase(protocol)) {
                    updateSslConfig(asyncClientBuilder, opts);
                }

                clientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> asyncClientBuilder);
                client = new RestHighLevelClient(clientBuilder);

                EsConnectionPoller esConnectionPoller = new EsConnectionPoller(
                    client, 0, POLL_INTERVAL_SECS, Math.toIntExact(opts.getPollingTime())
                );

                // Block and wait for Elasticsearch. Exception will be raised if not successful.
                esConnectionPoller.blockUntilReady();

                // Put client into list if polling is successful
                clients.put(clientKey, client);
                LOGGER.info("Created new Elasticsearch client for {0}://{1}:{2} for index prefix {3}",
                            protocol, host, port, indexNamePrefix);
            }

            if (opts.isInitialize()) {
                this.initializeIndices(client, esIndexes, indexNamePrefix);
            }

            return client;
        }
    }
Creates an HTTP/REST client from a configuration map.

@return the ES client
common/es/src/main/java/io/apiman/common/es/util/DefaultEsClientFactory.java