通过RestHighLevelClient兼容模式连接Elasticsearch8.x(支持https)
基于RestHighLevelClient7.17.7:
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ElasticsearchClientService {
public static RestHighLevelClient getClient(ElasticsearchClientConfig elasticsearchClientConfig) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, CertificateException, IOException {
List<ClientConfig> configList = elasticsearchClientConfig.getClientConfigs();
HttpHost[] httpHosts = new HttpHost[configList.size()];
for (int i = 0; i < configList.size(); i++) {
ClientConfig config = configList.get(i);
httpHosts[i] = new HttpHost(config.getHostname(), config.getPort(), elasticsearchClientConfig.getScheme());
}
boolean isSsl = false;
SSLContext sslContext = null;
if ("https".equalsIgnoreCase(elasticsearchClientConfig.getScheme()) && !StringUtil.isEmpty(elasticsearchClientConfig.getCaCertificatePath())) {
isSsl = true;
Path caCertificatePath = Paths.get(elasticsearchClientConfig.getCaCertificatePath());
CertificateFactory factory = CertificateFactory.getInstance("X.509");
Certificate trustedCa;
try (InputStream is = Files.newInputStream(caCertificatePath)) {
trustedCa = factory.generateCertificate(is);
}
KeyStore trustStore = KeyStore.getInstance("pkcs12");
trustStore.load(null, null);
trustStore.setCertificateEntry("ca", trustedCa);
SSLContextBuilder sslContextBuilder = SSLContexts.custom().loadTrustMaterial(trustStore, null);
sslContext = sslContextBuilder.build();
log.info("SSL连接elastic:已加载ca证书");
}
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(
elasticsearchClientConfig.getUserName(), elasticsearchClientConfig.getPassword()));
boolean finalIsSsl = isSsl;
SSLContext finalSslContext = sslContext;
RestClientBuilder restClientBuilder = RestClient
.builder(httpHosts)
.setHttpClientConfigCallback(customizeHttpClient -> {
customizeHttpClient.setDefaultCredentialsProvider(credentialsProvider);
if (finalIsSsl) {
customizeHttpClient.setSSLContext(finalSslContext);
}
return customizeHttpClient;
});
return new RestHighLevelClientBuilder(restClientBuilder.build()).setApiCompatibilityMode(true).build();
}
}
下面是一个https但不使用证书的例子:
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ElasticsearchClient {
private static RestHighLevelClient client = null;
public static RestHighLevelClient getClient() {
if (client != null) {
return client;
}
synchronized (ElasticsearchClient.class) {
if (client == null) {
client = build();
log.info("elastic连接已创建");
}
}
return client;
}
@SneakyThrows
private static RestHighLevelClient build() {
Properties prop = PropertiesUtils.get(Module.COMMON);
List<HttpHost> httpHosts = new ArrayList<>();
int i = 0;
String scheme = prop.getProperty("elasticsearch.scheme");
while (prop.containsKey("elasticsearch.client-configs[" + i + "].hostname")) {
httpHosts.add(new HttpHost(prop.getProperty("elasticsearch.client-configs[" + i + "].hostname"),
Integer.parseInt(prop.getProperty("elasticsearch.client-configs[" + i + "].port")),
scheme));
i++;
}
boolean isSsl = false;
SSLContext sslContext = null;
if ("https".equalsIgnoreCase(scheme)) {
isSsl = true;
log.info("启用SSL");
// 信任所有
sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
}
String userName = prop.getProperty("elasticsearch.userName");
String password = prop.getProperty("elasticsearch.password");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(
userName, password));
boolean finalIsSsl = isSsl;
SSLContext finalSslContext = sslContext;
RestClientBuilder restClientBuilder = RestClient
.builder(httpHosts.toArray(new HttpHost[]{}))
.setHttpClientConfigCallback(customizeHttpClient -> {
customizeHttpClient.setDefaultCredentialsProvider(credentialsProvider);
if (finalIsSsl) {
customizeHttpClient.setSSLContext(finalSslContext);
}
return customizeHttpClient;
});
return new RestHighLevelClientBuilder(restClientBuilder.build()).setApiCompatibilityMode(true).build();
}
@SneakyThrows
public static void close() {
if (client == null) {
return;
}
log.info("elastic连接关闭...");
client.close();
}
}