如何将“spring boot 2.1 with elasticsearch 6.6"与集群节点“https"连接? [英] How to connect 'spring boot 2.1 with elasticsearch 6.6' with cluster node 'https'?

查看:18
本文介绍了如何将“spring boot 2.1 with elasticsearch 6.6"与集群节点“https"连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个涉及模糊搜索的新项目,因此正在使用 spring boot (v2.1.5) 开发 elasticsearch (v6.4.3).我无法在 spring boot 和 elasticsearch 之间建立连接,因为我必须将用户名、密码、ca_certificate_base64 从 spring boot 传递到 elasticsearch 才能建立连接.您能否让我知道如何建立连接以及哪个 elasticsearch 客户端是正确的选项?示例或链接会有所帮助.

在本地(我的笔记本电脑),我确实安装了 elasticsearch 6 和 spring boot 2.1.5.我能够建立连接(使用 spring 数据),因为不需要https"连接或传递用户名和密码,因为互联网上的大多数示例都在谈论 localhost:9200.

 public Client client() {设置 elasticsearchSettings = Settings.builder().put("client.transport.sniff", true).put("uri", "https://usertemp:ABCSAD@alp-usba-north-3-portal.11.db2lay.com:32117/").put("uri_direct_1", "https://usertemp:ABCSAD@alp-usba-north-3-portal.11.db2lay.com:32117/").put("cluster.name", clusterName).build();TransportClient 客户端 = new PreBuiltTransportClient(elasticsearchSettings);}我也尝试更新 application.properties 文件'''spring.data.elasticsearch.cluster-name=ee842f-93042spring.data.elasticsearch.cluster-nodes=alp-usba-north-3-portal.11.db2lay.com:32117spring.data.elasticsearch.properties.username=usertempspring.data.elasticsearch.properties.password=ABCSADspring.data.elasticsearch.properties.ca_certificate_base64=SUZJQ0FURS0tLS0tCk1JSURvekNDQW91Z0F3SUJBZ0lFWFA5Sjl6QU5CZ2

我期待与 spring boot 和 elasticsearch 的连接.但是,当我启动应用程序服务器时出现以下错误.

<前>引起:org.springframework.beans.BeanInstantiationException:无法实例化[org.elasticsearch.client.transport.TransportClient]:工厂方法'elasticsearchClient'抛出异常;嵌套异常是 java.lang.IllegalArgumentException: unknown setting [password] 请检查是否安装了任何必需的插件,或检查已删除设置的破坏性更改文档在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]在 org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]...省略了 96 个常用帧引起:java.lang.IllegalArgumentException: unknown setting [password] 请检查是否安装了任何必需的插件,或检查已删除设置的破坏性更改文档在 org.elasticsearch.common.settings.AbstractScopedSettings.validate(AbstractScopedSettings.java:393) ~[elasticsearch-6.4.3.jar:6.4.3]

解决方案

正如我在评论中已经提到的,我不知道 IBM Compose for Elasticsearch 究竟是如何设置连接安全性的;我对这个场景的设置如下:

弹性搜索

  • 在我的机器上运行 Elasticsearch 6.6.2
  • 在 Elasticsearch 前面作为代理运行的 NGINX
    • 已激活基本身份验证
    • 仅限 SSL
    • 需要 SSL 客户端证书

maven 和版本

为了能够通过 HTTPS 进行通信,您需要使用 RestClient,它在 Spring Data Elasticsearch 3.2 版中可用(目前在 3.2.0.M4 版中可用).Spring Boot 2.1.5 引入了 Spring Data Elasticsearch 3.1.8,因此您需要覆盖该版本.您还需要指定 Elasticsearch 版本以匹配 Spring Boot Data 3.2.0.M4,因此您的 pom.xml 需要以下条目:

<java.version>1.8</java.version><elasticsearch.version>6.7.2</elasticsearch.version><spring-data-elasticsearch>3.2.0.M4</spring-data-elasticsearch></属性><存储库><存储库><id>spring-libs-snapshot</id><name>Spring 快照存储库</name><url>https://repo.spring.io/libs-milestones</url></repository></repositories><依赖项><依赖><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId><version>${spring-data-elasticsearch}</version></依赖></依赖项>

Bean 配置

在您的程序中,您可以使用 AbstractElasticsearchConfiguration 的实现为 Spring Data Elasticsearch 配置 Bean:

@Configuration公共类 RestClientConfig 扩展 AbstractElasticsearchConfiguration {私有静态最终记录器日志 = LoggerFactory.getLogger(RestClientConfig.class);private static final String CERT_FILE = "client.p12";private static final String CERT_PASSWORD = "topsecret";私有静态最终字符串USER_NAME =用户";私有静态最终字符串USER_PASS =密码";@覆盖公共 RestHighLevelClient elasticsearchClient() {最终 ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:443")//设置Elasticsearch集群地址.usingSsl(createSSLContext())//使用 SSLContext 和客户端证书.withBasicAuth(USER_NAME, USER_PASS)//使用标头进行身份验证.build();返回 RestClients.create(clientConfiguration).rest();}私有 SSLContext createSSLContext() {试试{SSLContext sslContext = SSLContext.getInstance("TLS");KeyManager[] keyManagers = getKeyManagers();sslContext.init(keyManagers, null, null);返回 sslContext;} 捕获(异常 e){LOG.error("无法创建 SSLContext", e);}返回空;}私人 KeyManager[] getKeyManagers()抛出 KeyStoreException、NoSuchAlgorithmException、IOException、CertificateException、UnrecoverableKeyException {尝试 (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(CERT_FILE)) {KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");clientKeyStore.load(inputStream, CERT_PASSWORD.toCharArray());KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(clientKeyStore, CERT_PASSWORD.toCharArray());返回 kmf.getKeyManagers();}}@豆@主要公共 ElasticsearchOperations elasticsearchTemplate() {返回弹性搜索操作();}}

通过此设置,我可以使用 ElasticsearchRestTemplateElasticsearchRepository 针对 Elasticsearch 集群运行我的 Spring Boot 应用程序.

您可能需要调整 getKeyManagers() 方法中的代码以匹配您从 Compose 获得的内容,但这应该为您提供一些起点.

I'm working on a new project which involves fuzzy search so was working on elasticsearch (v6.4.3) with spring boot (v2.1.5). I am unable to make connection between spring boot to elasticsearch since I have to pass username, password, ca_certificate_base64 from spring boot to elasticsearch to make connection. Could you please let me know how do I make connection and what elasticsearch client is correct option? A sample or link would be helpful.

Locally (my laptop), I did install elasticsearch 6 and spring boot 2.1.5. I was able to make connection (using spring data) since there was no 'https' connection required or pass username and password since most of the examples in internet talks about localhost:9200.

   public Client client() {
     Settings elasticsearchSettings = Settings.builder()
           .put("client.transport.sniff", true)
           .put("uri", "https://usertemp:ABCSAD@alp-usba-north-3-portal.11.db2lay.com:32117/")
           .put("uri_direct_1", "https://usertemp:ABCSAD@alp-usba-north-3-portal.11.db2lay.com:32117/")
           .put("cluster.name", clusterName).build();
      TransportClient client = new PreBuiltTransportClient(elasticsearchSettings);
}


I also tried to update application.properties file
'''
spring.data.elasticsearch.cluster-name=ee842f-93042
spring.data.elasticsearch.cluster-nodes=alp-usba-north-3-portal.11.db2lay.com:32117
spring.data.elasticsearch.properties.username=usertemp
spring.data.elasticsearch.properties.password=ABCSAD
spring.data.elasticsearch.properties.ca_certificate_base64=SUZJQ0FURS0tLS0tCk1JSURvekNDQW91Z0F3SUJBZ0lFWFA5Sjl6QU5CZ2

I was expecting the connection with spring boot and elasticsearch. But, getting below error when I start the application server.

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.elasticsearch.client.transport.TransportClient]: Factory method 'elasticsearchClient' threw exception; nested exception is java.lang.IllegalArgumentException: unknown setting [password] please check that any required plugins are installed, or check the breaking changes documentation for removed settings
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
    ... 96 common frames omitted
Caused by: java.lang.IllegalArgumentException: unknown setting [password] please check that any required plugins are installed, or check the breaking changes documentation for removed settings
    at org.elasticsearch.common.settings.AbstractScopedSettings.validate(AbstractScopedSettings.java:393) ~[elasticsearch-6.4.3.jar:6.4.3] 

解决方案

As I already mentioned in the comments, I don't know how exactly IBM Compose for Elasticsearch sets up the connection security; my setup for this scenario is as follows:

Elasticsearch

  • Elasticsearch 6.6.2 running on my machine
  • an NGINX running as proxy in front of Elasticsearch with
    • Basic Authentication activated
    • SSL only
    • SSL client certificates needed

maven and versions

In order to be able to communicate via HTTPS you need to use the RestClient which is available in Spring Data Elasticsearch as of version 3.2 (which currently is available in version 3.2.0.M4). Spring Boot 2.1.5 pulls in Spring Data Elasticsearch 3.1.8, so you need to override the version. You also need to specify the Elasticsearch version to match Spring Boot Data 3.2.0.M4, so your pom.xml needs the following entries:

<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>6.7.2</elasticsearch.version>
    <spring-data-elasticsearch>3.2.0.M4</spring-data-elasticsearch>
</properties>

<repositories>
    <repository>
        <id>spring-libs-snapshot</id>
        <name>Spring Snapshot Repository</name>
        <url>https://repo.spring.io/libs-milestones</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>${spring-data-elasticsearch}</version>
    </dependency>
</dependencies>

Bean configuration

In your program you can configure the Beans for Spring Data Elasticsearch with an implementation of AbstractElasticsearchConfiguration:

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {

    private static final Logger LOG = LoggerFactory.getLogger(RestClientConfig.class);

    private static final String CERT_FILE = "client.p12";
    private static final String CERT_PASSWORD = "topsecret";
    private static final String USER_NAME = "user";
    private static final String USER_PASS = "password";

    @Override
    public RestHighLevelClient elasticsearchClient() {

        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("localhost:443")  // set the address of the Elasticsearch cluster
                .usingSsl(createSSLContext())  // use the SSLContext with the client cert
                .withBasicAuth(USER_NAME, USER_PASS)   // use the headers for authentication
                .build();

        return RestClients.create(clientConfiguration).rest();
    }

    private SSLContext createSSLContext() {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");

            KeyManager[] keyManagers = getKeyManagers();

            sslContext.init(keyManagers, null, null);

            return sslContext;
        } catch (Exception e) {
            LOG.error("cannot create SSLContext", e);
        }
        return null;
    }

    private KeyManager[] getKeyManagers()
            throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException, UnrecoverableKeyException {
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(CERT_FILE)) {
            KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
            clientKeyStore.load(inputStream, CERT_PASSWORD.toCharArray());

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(clientKeyStore, CERT_PASSWORD.toCharArray());
            return kmf.getKeyManagers();
        }
    }

    @Bean
    @Primary
    public ElasticsearchOperations elasticsearchTemplate() {
        return elasticsearchOperations();
    }
}

With this setup I can run my Spring Boot application against the Elasticsearch cluster using ElasticsearchRestTemplate and ElasticsearchRepository.

You probably need to adjust the code in the getKeyManagers() method to match what you have from Compose, but this should give you some point from where to start.

这篇关于如何将“spring boot 2.1 with elasticsearch 6.6"与集群节点“https"连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆