透過RestHighLevelClient相容模式連線elasticsearch8.x(支援https)

用户名还没想好發表於2024-05-16

基於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();
  }

}

相關文章