Spring Data Elasticsearch是否支持Amazon Elasticsearch?

15

根据我所做的研究,似乎由于Amazon Elasticsearch仅支持HTTP,所以这两者不能一起使用。

希望有人能澄清,是否Spring Data Elasticsearch也不支持这种情况。

5个回答

7

看起来从3.2.0版本开始,Spring data elastic search可以使用http rest client工作,因此可以通过Rest API和端口443连接到AWS Elastic实例。不知何故,他们将spring-data-jest方法集成到Spring数据中。 我使用RestHighLevelClient:

    @Bean
    public RestHighLevelClient client() {
        return new RestHighLevelClient(RestClient.builder(HttpHost.create(awsUrl)));
    }

awsUrl 的格式为:https://some_aws_generated_address.us-east-n.es.amazonaws.com:443

注意:如果您正在使用默认的 bom.xml 的 spring boot,您需要将 spring boot 升级至 2.2.1.RELEASE 或更高版本。


5

可以的,请参考 https://dev59.com/oFsX5IYBdhLWcg3wS9w7#61193214 - Prasanth Rajendran

2

1
可以使用Spring Data Elasticsearch与Amazon Elasticsearch 从Spring-data elastic search doc摘录如下:
TransportClient在Elasticsearch 7中已被弃用,并将在Elasticsearch 8中删除。这是为了支持Java High Level REST Client。只要TransportClient在Elasticsearch中可用,Spring Data Elasticsearch将支持它。
Java High Level REST Client现在是Elasticsearch的默认客户端,它提供了一个直接替代TransportClient的方案,因为它接受和返回完全相同的请求/响应对象,因此依赖于Elasticsearch核心项目。

Spring Data ElasticSearch已与最新的ElasticSearch标准整合,因此从spring-data-elasticsearch:3.2.X开始,它提供了一种灵活的方式来实现自定义的RestHighLevelClient。(link) 虽然可以使用基于HTTP的ElasticSearch API调用,无论是否进行身份验证,但这不会解决与AWS ElasticSearch API调用相关的问题。

因为任何针对AWS服务或APIGW支持的服务HTTP请求都必须遵循"签名版本4签名过程(SigV4)",最终通过HTTP发送的AWS请求将添加身份验证信息。出于安全考虑,大多数对AWS的请求必须使用访问密钥进行签名,其中包括一个accesskey ID和一个secret access key。因此,在调用AWS ElasticSearch服务时,我们必须遵循标准。

让我们动手编码,深入了解实现细节

请按照以下步骤操作:
第一步:添加所需的依赖项。
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-elasticsearch</artifactId>
            <version>1.11.346</version>
        </dependency>

步骤2:添加AWS CredentialsProvider
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AWSCredentialsConfiguration {

    @Value("${aws.es.accessKey}")
    private String esAccessKey = null;

    @Value("${aws.es.secretKey}")
    private String esSecretKey = null;

    @Bean
    public AWSStaticCredentialsProvider awsDynamoCredentialsProviderDevelopment() {
        return new AWSStaticCredentialsProvider(new BasicAWSCredentials(
                esAccessKey, esSecretKey));
    }
}

如果您的应用程序在 AWS 实例上运行,且不想使用基于属性驱动/硬编码的 AccessKey 和 SecretKey,则必须为您的 Amazon ECS 任务分配 IAM 角色 了解更多

import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AWSCredentialsConfiguration {

    @Bean
    public AWSCredentialsProvider amazonAWSCredentialsProvider() {
        return new EC2ContainerCredentialsProviderWrapper();
    }

}

步骤 3:添加 ElasticSearchRestClientConfiguration

  • 如果您观察下面的代码,我们提供了一个自定义实现的 **RestHighLevelClient** 给抽象方法 **AbstractElasticsearchConfiguration#elasticsearchClient()**。通过这种方式,我们将 "elasticsearchOperations""elasticsearchTemplate" bean 中包含的 customRestHighLevelClient 注入到 spring 容器中。
  • HttpRequestInterceptor 是另一个需要注意的重要事项。特别感谢 AWSRequestSigningApacheInterceptor.java,由AWSLabs 提供的示例实现帮助我们使用 AWS4Signer 机制向 RestClient 添加拦截器。
  • @EnableElasticsearchRepositories 注释有助于启用 elasticsearch 数据存储库。
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.auth.AWSCredentialsProvider;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;


@Configuration
@EnableElasticsearchRepositories(basePackages = "com.demo.aws.elasticsearch.data.repository")
public class ElasticSearchRestClientConfiguration extends AbstractElasticsearchConfiguration {

    @Value("${aws.es.endpoint}")
    private String endpoint = null;

    @Value("${aws.es.region}")
    private String region = null;

    @Autowired
    private AWSCredentialsProvider credentialsProvider = null;

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        AWS4Signer signer = new AWS4Signer();
        String serviceName = "es";
        signer.setServiceName(serviceName);
        signer.setRegionName(region);
        HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor(serviceName, signer, credentialsProvider);
        return new RestHighLevelClient(RestClient.builder(HttpHost.create(endpoint)).setHttpClientConfigCallback(e -> e.addInterceptorLast(interceptor)));
    }
}

干得好!就是这样。我们已经完成了配置部分。现在,通过此解决方案,您可以利用spring-data elastic的优势以及Amazon弹性搜索服务。完整的解决方案已在Medium Post中记录。

如果涉及访问索引(例如刷新)的权限问题,请使用answer添加权限。


不起作用。我得到了[HTTP/1.1 403 Forbidden] {"message":"我们计算的请求签名与您提供的签名不匹配。检查您的AWS Secret Access Key和签名方法。请参阅服务文档以获取详细信息。"}]。直接通过RestHighLevelClient连接可以工作。 - shark
@shark,对于相应的错误,您需要检查您的AWSCredentialsProvider。请验证您的凭证accessKeysecretId。我已经在超过2个微服务中使用了这个片段。我没有遇到过403问题。 - Prasanth Rajendran
我应该针对权限、角色等方面做些什么吗?我的实例是公共的。 - shark
@Vinod,它应该可以与spring-boot-starter-data-elasticsearch:2.2.2.RELEASE和aws-java-sdk-elasticsearch:1.11.346一起使用。我已经在生产环境中使用上述版本运行应用程序。 - Prasanth Rajendran
@PrasanthRajendran 我曾遇到类似的问题,现在可能有多种原因导致这种情况:为了验证,请从Spring boot端点插入任何记录到AWS Elasticsearch,并检查您是否能够在Kibana视图中看到记录,如果您看到记录被插入但仍然出现403错误,那是因为AWSRequestSigningApacheInterceptor.java文件出错,请从Github(awslabs)获取文件。在这种情况下,按id搜索并查找所有应该可以正常工作。第二种情况可能是版本问题,请检查Elasticsearch版本和spring boot父版本。 - Vinod
显示剩余3条评论

0

我在与 AWS ES 堆栈相同的配置中遇到了以下错误,就像这篇文章https://medium.com/@prasanth_rajendran/how-to-integrate-spring-boot-elasticsearch-data-with-aws-445e6fc72998所示。

Error creating bean with name 'supplierContacts' defined in file ... Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'supplierContactListDaoImpl' defined in file [SupplierContactListDaoImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'supplierContactListRepository': Cannot resolve reference to bean 'elasticsearchTemplate' while setting bean property 'elasticsearchOperations'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'elasticsearchOperations' defined in class path resource [ElasticSearchConfig.class]: Unsatisfied dependency expressed through method 'elasticsearchOperations' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticsearchEntityMapper' defined in class path resource [ElasticSearchConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter]: Factory method 'elasticsearchEntityMapper' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/mapping/model/EntityInstantiators

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接