如何连接 'spring boot 2.1 with elasticsearch 6.6' 和集群节点 'https'?
How to connect 'spring boot 2.1 with elasticsearch 6.6' with cluster node 'https'?
我正在开发一个涉及模糊搜索的新项目,因此我正在使用 spring 引导 (v2.1.5) 开发 elasticsearch (v6.4.3)。我无法在 spring 引导到 elasticsearch 之间建立连接,因为我必须将用户名、密码、ca_certificate_base64 从 spring 引导传递到 elasticsearch 以建立连接。您能否告诉我如何建立连接以及哪个 elasticsearch 客户端是正确的选择?示例或 link 会有所帮助。
在本地(我的笔记本电脑),我确实安装了 elasticsearch 6 和 spring boot 2.1.5。我能够建立连接(使用 spring 数据),因为不需要 'https' 连接或传递用户名和密码,因为互联网上的大多数示例都在讨论 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
我期待与 spring boot 和 elasticsearch 的连接。但是,当我启动应用程序服务器时出现以下错误。
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]
正如我在评论中提到的,我不知道 IBM Compose for Elasticsearch 究竟是如何设置连接安全性的;我对此场景的设置如下:
弹性搜索
- Elasticsearch 6.6.2 运行在我的机器上运行
- 一个 NGINX 运行ning 作为 Elasticsearch 前面的代理
- 已激活基本身份验证
- 仅 SSL
- 需要 SSL 客户端证书
maven 和版本
为了能够通过 HTTPS 进行通信,您需要使用 Spring Data Elasticsearch 3.2 版中可用的 RestClient
(目前在 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 需要以下条目:
<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 配置
在您的程序中,您可以为 Spring Data Elasticsearch 配置 Bean,实现 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();
}
}
通过此设置,我可以 运行 我的 Spring 使用 ElasticsearchRestTemplate
和 ElasticsearchRepository
.
针对 Elasticsearch 集群启动应用程序
您可能需要调整 getKeyManagers()
方法中的代码以匹配您从 Compose 中获得的代码,但这应该为您提供一些起点。
我正在开发一个涉及模糊搜索的新项目,因此我正在使用 spring 引导 (v2.1.5) 开发 elasticsearch (v6.4.3)。我无法在 spring 引导到 elasticsearch 之间建立连接,因为我必须将用户名、密码、ca_certificate_base64 从 spring 引导传递到 elasticsearch 以建立连接。您能否告诉我如何建立连接以及哪个 elasticsearch 客户端是正确的选择?示例或 link 会有所帮助。
在本地(我的笔记本电脑),我确实安装了 elasticsearch 6 和 spring boot 2.1.5。我能够建立连接(使用 spring 数据),因为不需要 'https' 连接或传递用户名和密码,因为互联网上的大多数示例都在讨论 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
我期待与 spring boot 和 elasticsearch 的连接。但是,当我启动应用程序服务器时出现以下错误。
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]
正如我在评论中提到的,我不知道 IBM Compose for Elasticsearch 究竟是如何设置连接安全性的;我对此场景的设置如下:
弹性搜索
- Elasticsearch 6.6.2 运行在我的机器上运行
- 一个 NGINX 运行ning 作为 Elasticsearch 前面的代理
- 已激活基本身份验证
- 仅 SSL
- 需要 SSL 客户端证书
maven 和版本
为了能够通过 HTTPS 进行通信,您需要使用 Spring Data Elasticsearch 3.2 版中可用的 RestClient
(目前在 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 需要以下条目:
<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 配置
在您的程序中,您可以为 Spring Data Elasticsearch 配置 Bean,实现 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();
}
}
通过此设置,我可以 运行 我的 Spring 使用 ElasticsearchRestTemplate
和 ElasticsearchRepository
.
您可能需要调整 getKeyManagers()
方法中的代码以匹配您从 Compose 中获得的代码,但这应该为您提供一些起点。