You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AWS SDK v1时,如何用Apache HttpClient5/RestClient连接AWS OpenSearch

基于AWS SDK v1,通过Apache Transport连接AWS OpenSearch集群

由于你使用AWS SDK v1且无法弃用相关依赖,同时高级REST客户端已被标记为弃用,以下是两种可行的实现方案,核心是通过AWS SDK v1的签名工具为请求添加AWS身份验证签名,结合OpenSearch的Apache Transport客户端完成连接。

方案1:使用Apache RestClient Transport(基于Apache HttpClient 4.x)

1. 依赖配置(Maven)

<!-- OpenSearch Java Client -->
<dependency>
    <groupId>org.opensearch.client</groupId>
    <artifactId>opensearch-java</artifactId>
    <version>2.11.0</version> <!-- 替换为与集群兼容的版本 -->
</dependency>
<!-- OpenSearch RestClient Transport -->
<dependency>
    <groupId>org.opensearch.client</groupId>
    <artifactId>opensearch-rest-client</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- AWS SDK v1 Core -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-core</artifactId>
    <version>1.12.500</version> <!-- 替换为你正在使用的SDK v1版本 -->
</dependency>
<!-- Apache HttpClient 4.x -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

2. 实现AWS签名拦截器

创建HttpClient拦截器,用AWS SDK v1的AWS4Signer对请求签名:

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.Signer;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.regions.Regions;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.protocol.HttpContext;
import java.io.IOException;
import java.net.URI;

public class AwsRequestSigningInterceptor implements HttpRequestInterceptor {
    private final Signer signer;
    private final AWSCredentialsProvider credentialsProvider;
    private final String serviceName;
    private final String region;

    public AwsRequestSigningInterceptor(String serviceName, String region) {
        this.signer = new AWS4Signer();
        this.credentialsProvider = new DefaultAWSCredentialsProviderChain();
        this.serviceName = serviceName;
        this.region = region;
        ((AWS4Signer) this.signer).setServiceName(serviceName);
        ((AWS4Signer) this.signer).setRegionName(region);
    }

    @Override
    public void process(HttpRequest request, HttpContext context) throws IOException {
        URI uri = URI.create(request.getRequestLine().getUri());
        com.amazonaws.http.HttpRequest awsRequest = new com.amazonaws.http.HttpRequest(
            com.amazonaws.http.HttpMethodName.fromValue(request.getRequestLine().getMethod()),
            uri
        );

        // 复制原请求头
        request.getAllHeaders().forEach(header -> awsRequest.addHeader(header.getName(), header.getValue()));

        // 执行签名
        signer.sign(awsRequest, credentialsProvider.getCredentials());

        // 将签名后的头写回原请求
        awsRequest.getHeaders().forEach((key, values) -> {
            request.removeHeaders(key);
            values.forEach(value -> request.addHeader(key, value));
        });
    }
}

3. 创建OpenSearchClient实例

import org.apache.http.HttpHost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientBuilder;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.rest_client.RestClientTransport;

public class OpenSearchAwsClientFactory {
    public static OpenSearchClient createClient(String opensearchEndpoint, String region) {
        // 解析OpenSearch集群端点
        HttpHost host = HttpHost.create(opensearchEndpoint);

        // 构建带签名拦截器的HttpClient
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.addInterceptorFirst(new AwsRequestSigningInterceptor("es", region));

        // 构建RestClient
        RestClientBuilder restClientBuilder = RestClient.builder(host)
            .setHttpClientConfigCallback(builder -> httpClientBuilder);

        // 创建Transport和OpenSearchClient
        RestClientTransport transport = new RestClientTransport(
            restClientBuilder.build(),
            new JacksonJsonpMapper()
        );

        return new OpenSearchClient(transport);
    }

    // 测试示例
    public static void main(String[] args) {
        String endpoint = "https://your-opensearch-domain.us-east-1.es.amazonaws.com";
        String region = Regions.US_EAST_1.getName();
        OpenSearchClient client = createClient(endpoint, region);

        try {
            var response = client.info();
            System.out.println("集群名称: " + response.clusterName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方案2:使用Apache HttpClient 5 Transport

若需使用Apache HttpClient 5,核心逻辑一致,但拦截器和依赖配置需适配HttpClient 5的API:

1. 依赖配置(Maven)

<!-- OpenSearch Java Client -->
<dependency>
    <groupId>org.opensearch.client</groupId>
    <artifactId>opensearch-java</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- OpenSearch HttpClient 5 Transport -->
<dependency>
    <groupId>org.opensearch.client</groupId>
    <artifactId>opensearch-httpclient5</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- AWS SDK v1 Core -->
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-core</artifactId>
    <version>1.12.500</version>
</dependency>
<!-- Apache HttpClient 5 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.2.1</version>
</dependency>

2. 实现AWS签名拦截器(HttpClient 5版本)

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.Signer;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.regions.Regions;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.protocol.HttpContext;
import java.io.IOException;
import java.net.URI;

public class AwsRequestSigningInterceptor5 implements HttpRequestInterceptor {
    private final Signer signer;
    private final AWSCredentialsProvider credentialsProvider;
    private final String serviceName;
    private final String region;

    public AwsRequestSigningInterceptor5(String serviceName, String region) {
        this.signer = new AWS4Signer();
        this.credentialsProvider = new DefaultAWSCredentialsProviderChain();
        this.serviceName = serviceName;
        this.region = region;
        ((AWS4Signer) this.signer).setServiceName(serviceName);
        ((AWS4Signer) this.signer).setRegionName(region);
    }

    @Override
    public void process(HttpRequest request, HttpContext context) throws IOException {
        URI uri = URI.create(request.getRequestUri());
        com.amazonaws.http.HttpRequest awsRequest = new com.amazonaws.http.HttpRequest(
            com.amazonaws.http.HttpMethodName.fromValue(request.getMethod()),
            uri
        );

        // 复制原请求头
        request.getHeaders().forEach(header -> awsRequest.addHeader(header.getName(), header.getValue()));

        // 执行签名
        signer.sign(awsRequest, credentialsProvider.getCredentials());

        // 将签名后的头写回原请求
        awsRequest.getHeaders().forEach((key, values) -> {
            request.removeHeaders(key);
            values.forEach(value -> request.addHeader(key, value));
        });
    }
}

3. 创建OpenSearchClient实例

import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.HttpHost;
import org.opensearch.client.httpclient5.HttpClient5Transport;
import org.opensearch.client.httpclient5.HttpClient5TransportBuilder;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;

public class OpenSearchAwsClientFactory5 {
    public static OpenSearchClient createClient(String opensearchEndpoint, String region) {
        HttpHost host = HttpHost.create(opensearchEndpoint);

        // 构建带签名拦截器的HttpClient 5
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.addRequestInterceptorFirst(new AwsRequestSigningInterceptor5("es", region));

        // 构建HttpClient5Transport
        HttpClient5Transport transport = HttpClient5TransportBuilder.builder(host)
            .setHttpClient(httpClientBuilder.build())
            .setMapper(new JacksonJsonpMapper())
            .build();

        return new OpenSearchClient(transport);
    }

    // 测试示例
    public static void main(String[] args) {
        String endpoint = "https://your-opensearch-domain.us-east-1.es.amazonaws.com";
        String region = Regions.US_EAST_1.getName();
        OpenSearchClient client = createClient(endpoint, region);

        try {
            var response = client.info();
            System.out.println("集群名称: " + response.clusterName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键注意事项

  • 确保OpenSearch Java Client版本与AWS OpenSearch集群版本兼容(如集群2.x对应客户端2.x系列)
  • DefaultAWSCredentialsProviderChain会自动从环境变量、系统属性、IAM角色等渠道获取凭证,适配EC2、ECS等AWS环境
  • AWS OpenSearch的服务签名标识固定为es
  • 替换代码中的集群端点和区域为实际值

内容的提问来源于stack exchange,提问作者contemplator

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:45:15