java 整合elasticsearch8.6.2 问题解决 .TransportException: [es/indices.exists] Miss
·
co.elastic.clients.transport.TransportException: [es/indices.exists] Missing [X-Elastic-Product] header
问题记录
这里记录一次 远程连接 es8.6.2,账号密码方式安全连接的一次问题解决,
**
注意*******:
es8.6.2安全连接参考地址:https://cloud.tencent.com/developer/article/2046642
补充, 按照以上地址配置es 理论上是不会出现[X-Elastic-Product] header 这个问题的,所以请先确认
es的证书(及服务器上配置es后生成的后缀名为 .crt文件)
es集群地址
以及账号密码配置
是否正确,如果都正确可以试试下面的办法,希望能给你带来帮助
ClientConfig 的111行 及方法getElasticsearchTransport 是解决问题的关键
ymal
spring.elasticsearch.uris=172.0.0.1:9200,172.0.0.2:9200,172.0.0.3:9200
spring.elasticsearch.username=root
spring.elasticsearch.password=123456
spring.elasticsearch.connection-timeout=10000
spring.elasticsearch.socket-timeout=30s
ClientConfig
package com.relaper.iot.es.app.test.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.List;
@ConfigurationProperties(prefix = "spring.elasticsearch") //配置的前缀
@Configuration
@Slf4j
public class ClientConfig {
@Setter
private String uris;
@Setter
private String username;
@Setter
private String passwd;
// @Setter
// private String apikey;
/**
* 解析配置的字符串,转为HttpHost对象数组
*
* @return
*/
private HttpHost[] toHttpHost() {
if (!StringUtils.hasLength(uris)) {
throw new RuntimeException("invalid elasticsearch configuration");
}
String[] hostArray = uris.split(",");
HttpHost[] httpHosts = new HttpHost[hostArray.length];
HttpHost httpHost;
for (int i = 0; i < hostArray.length; i++) {
String[] strings = hostArray[i].split(":");
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "https");
httpHosts[i] = httpHost;
}
return httpHosts;
}
@Bean("clientByPasswd")
public ElasticsearchClient clientByPasswd() throws Exception {
ElasticsearchTransport transport = getElasticsearchTransport(username, passwd, toHttpHost());
return new ElasticsearchClient(transport);
}
private static SSLContext buildSSLContext() {
ClassPathResource resource = new ClassPathResource("es01.crt");
SSLContext sslContext = null;
try {
CertificateFactory factory = CertificateFactory.getInstance("X.509");
Certificate trustedCa;
try (InputStream is = resource.getInputStream()) {
trustedCa = factory.generateCertificate(is);
}
KeyStore trustStore = KeyStore.getInstance("pkcs12");
trustStore.load(null, null);
trustStore.setCertificateEntry("ca", trustedCa);
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(trustStore, null);
sslContext = sslContextBuilder.build();
} catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException |
KeyManagementException e) {
log.error("ES连接认证失败", e);
}
return sslContext;
}
private static ElasticsearchTransport getElasticsearchTransport(String username, String passwd, HttpHost... hosts) {
// 账号密码的配置
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, passwd));
// 自签证书的设置,并且还包含了账号密码
HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
// .setSSLContext(buildSSLContext()) // 证书式认证方式
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setDefaultCredentialsProvider(credentialsProvider)
// Todo 这里是关键 ######################解决 X-Elastic-Product 问题开始
.setDefaultHeaders(
List.of(
new BasicHeader(
HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())))
.addInterceptorLast(
(HttpResponseInterceptor)
(response, context) ->
response.addHeader("X-Elastic-Product", "Elasticsearch"));
// X-Elastic-Product end
// 用builder创建RestClient对象
RestClient client = RestClient
.builder(hosts)
.setHttpClientConfigCallback(callback)
.build();
return new RestClientTransport(client, new JacksonJsonpMapper());
}
private static ElasticsearchTransport getElasticsearchTransport(String apiKey, HttpHost... hosts) {
// 将ApiKey放入header中
Header[] headers = new Header[]{new BasicHeader("Authorization", "ApiKey " + apiKey)};
// es自签证书的设置
HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
.setSSLContext(buildSSLContext())
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
// 用builder创建RestClient对象
RestClient client = RestClient
.builder(hosts)
.setHttpClientConfigCallback(callback)
.setDefaultHeaders(headers)
.build();
return new RestClientTransport(client, new JacksonJsonpMapper());
}
// @Bean
// public ElasticsearchClient clientByApiKey() throws Exception {
// ElasticsearchTransport transport = getElasticsearchTransport(apikey, toHttpHost());
// return new ElasticsearchClient(transport);
// }
}
好了以上配置文件亲测可用,希望能帮助到各位,节省各位的宝贵时间,88
参考文献:
https://stackoverflow.com/questions/71142680/co-elastic-clients-transport-transportexception-es-search-missing-x-elastic
更多推荐
所有评论(0)