How to properly close a connection in a Java API Client?

Configuration Sample Code

@ApplicationScoped
public class ElasticSearchConfiguration {

    private static ElasticsearchClient client;

    private static synchronized void connectElasticSearchCluster() {
        if (Objects.nonNull(client)) {
            return;
        }
        final CredentialsProvider credentialsProvider =
                new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(ELASTIC_USER, ELASTIC_PASSWORD));
        RestClientBuilder builder = RestClient.builder(initializeHttpHost())
                .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
                        .setDefaultCredentialsProvider(credentialsProvider));

        // init RestClient only once
        RestClient restClient = builder.build();
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());
        client = new ElasticsearchClient(transport);
    }

    private static HttpHost[] initializeHttpHost() {
        List<String> hosts = Splitter.on(",").splitToList(ELASTIC_CLUSTER_HOST);
        List<HttpHost> result = Lists.newArrayList();
        hosts.forEach(item -> {
            HttpHost httpHost = HttpHost.create(item);
            result.add(httpHost);
        });
        return result.toArray(new HttpHost[hosts.size()]);
    }

    public ElasticsearchClient openConnection() {
        if (Objects.isNull(client) && ENABLE_ELASTIC) {
            connectElasticSearchCluster();
        }
        return client;
    }
}

Usage Sample Code

@ApplicationScoped
public class SearchService {

    @Inject
    private ElasticSearchConfiguration elasticSearchConfiguration;

    private List<Long> paginationQuery(List<String> queryIndexNames, Query query) {

	    ElasticsearchClient elasticsearchClient = elasticSearchConfiguration.openConnection();

		SearchResponse<TestDocument> searchResponse = elasticsearchClient.search(builder.build(), TestDocument.class);
		...
        return new ArrayList<>();
    }
}

According to the official documentation

The RestClient class is thread-safe and ideally has the same lifecycle as the application that uses it

So I think RestClient should be singleton.for the same reason, I think Java API clients, such as ElasticsearchClient, should also be singleton.

When the application shut down, I want to close the ElasticsearchClient, I found that there is no close method, only the client._transport().close() method; should I use this method? Or should I make RestClient also a static property and use RestClient.close() method, if so, doesn't ElasticsearchClient need to be closed?

Can someone answer this question?

Welcome!

You only need to close the ElasticsearchTransport object.

invoke client._transport().close() method,right?

I'd make transport a private static field of the class and call transport.close().

Thank you very much for your answer :+1: :+1

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.