【问题标题】:Does Spring Data Elasticsearch support Amazon Elasticsearch?Spring Data Elasticsearch 是否支持 Amazon Elasticsearch?
【发布时间】:2016-03-04 18:06:00
【问题描述】:

从我所做的研究看来,这两者似乎不能一起工作,因为 HTTP 仅支持 Amazon Elasticsearch。

希望有人能澄清一下 Spring Data Elasticsearch 是否无法实现这一点。

【问题讨论】:

    标签: spring spring-data spring-data-elasticsearch amazon-elasticsearch


    【解决方案1】:

    可以将 Spring Data Elasticsearch 与 Amazon Elasticsearch 结合使用

    摘自 Spring-data 弹性搜索doc

    TransportClient 自 Elasticsearch 7 起已弃用,并将 在 Elasticsearch 8 中删除。这有利于 Java 高级 REST 客户。 Spring Data Elasticsearch 将支持 TransportClient 作为 只要它在 Elasticsearch 中可用。

    Java 高级 REST 客户端现在是默认客户端 Elasticsearch,它为 TransportClient 因为它接受并返回相同的 请求/响应对象,因此依赖于 Elasticsearch 核心项目

    Spring Data ElasticSearch 已根据 ElasticSearch 的最新标准进行了精简,因此从 spring-data-elasticsearch:3.2.X 它提供了一种灵活的方式来实现自定义 RestHighLevelClient。(@987654322 @) 即使可以使用基于 HTTP 的弹性搜索 API 调用(有或没有身份验证),但它不会解决与 AWS 弹性搜索 API 调用相关的问题。

    因为对 AWS 服务或 APIGW 支持的服务 的任何 HTTP 请求 都必须遵循 "Signature Version 4 Signing Process(SigV4)" 最终将身份验证信息添加到发送的 AWS 请求中通过 HTTP。为安全起见,大多数对 AWS 的请求都必须使用访问密钥进行签名,该密钥由 accesskey IDsecret access key 组成。因此,我们在调用 AWS ElasticSearch 服务时必须遵循标准。

    让我们动手编写代码并深入研究实现

    请按以下步骤操作:

    第 1 步:添加所需的依赖项

           <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,那么您必须将 IAM 角色分配给您的 Amazon ECS任务 for more.

    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

    • 如果您观察到下面的代码,我们正在为抽象方法**AbstractElasticsearchConfiguration#elasticsearchClient()** 提供**RestHighLevelClient** 的自定义实现。这样,我们将 "elasticsearchOperations""elasticsearchTemplate" bean 合并的 customRestHighLevelClient 注入到 spring 容器中。
    • HttpRequestInterceptor 是另一个需要注意的重要事项。特别感谢AWSRequestSigningApacheInterceptor.javaAWSLabs提供的示例实现帮助我们通过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 弹性优势以及 Amazon 弹性搜索服务。完整的解决方案已记录在Medium Post

    如果有任何与访问索引的权限相关的问题(例如:刷新),您可以使用answer添加权限

    【讨论】:

    • 不起作用。我收到 [HTTP/1.1 403 Forbidden] {"message":"我们计算的请求签名与您提供的签名不匹配。请检查您的 AWS 秘密访问密钥和签名方法。有关详细信息,请参阅服务文档。"}] .通过 RestHighLevelClient 直接连接时有效
    • @shark,对于相应的错误,你必须检查你的AWSCredentialsProvider。请验证您的凭据accessKeysecretId。我已经将这个 sn-p 用于 2 个以上的微服务。没见过这样的403问题
    • 我有 DefaultAWSCredentialsProviderChain 并且我还检查了它是否需要有效的密钥并且确实如此。奇怪的是此代码正确创建索引但存储实体有问题
    • 我应该对权限、角色等做一些具体的事情吗?我的实例是公开的
    • DefaultAWSCredentialsProviderChain 按以下顺序获取凭证。 ` 环境变量或 Java 系统属性或 Web 身份令牌凭证来自所有 AWS 开发工具包和 AWS CLI 共享的默认位置 (~/.aws/credentials) 的环境或容器或凭证配置文件 `。索引创建工作正常意味着您的 API 调用身份验证工作正常,您必须检查您的 AWS 服务的角色,您是否有权执行索引的写入操作。
    【解决方案2】:

    我在与 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
    

    【讨论】:

      【解决方案3】:

      看起来 3.2.0 版的 Spring 数据弹性搜索与 http rest 客户端一起工作,因此可以通过 Rest API 和端口 443 连接到 aws 弹性实例。他们以某种方式将 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 或更新版本

      【讨论】:

        【解决方案4】:

        有一个很好的项目提供 Spring Data ES 的 Jest 实现,它与 AWS 托管的 ES 服务一起使用。

        结帐 https://github.com/VanRoy/spring-data-jest

        【讨论】:

          【解决方案5】:

          来自不同的讨论:
          - Spring data ES and searchly
          - port for the transport protocol

          AWS documentation on ES service limitations;转到底部,最后一行说:

          该服务在端口 80 上支持 HTTP,但不支持 TCP 传输。

          目前还不能使用使用 Java API 的 Spring Data ES,以及只能通过 REST 获得的 Amazon 服务。

          【讨论】:

          猜你喜欢
          • 2022-09-25
          • 2017-06-19
          • 2018-10-15
          • 2017-12-14
          • 1970-01-01
          • 1970-01-01
          • 2014-12-23
          • 2021-01-14
          • 1970-01-01
          相关资源
          最近更新 更多