mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
微服务基础模块:1、数据库、redis账号密码解密配置类注入方式修改;2、elasticsearch支持账号密码解密、支持https;
This commit is contained in:
+114
-28
@@ -4,16 +4,42 @@ import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
|
||||
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||
import co.elastic.clients.transport.rest_client.RestClientTransport;
|
||||
import com.cf.imes.framework.common.util.encrypt.AesUtils;
|
||||
import com.cf.imes.framework.es.core.service.ESDocumentService;
|
||||
import com.cf.imes.framework.es.core.service.ESDocumentServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* @author there
|
||||
@@ -21,20 +47,19 @@ import org.springframework.util.StringUtils;
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(ElasticsearchClient.class)
|
||||
@EnableConfigurationProperties(EsProperties.class)
|
||||
@Slf4j
|
||||
public class ChenfengElasticsearchAutoConfiguration {
|
||||
|
||||
//超时时间设置
|
||||
public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 10000;
|
||||
public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 300000;
|
||||
public static final int DEFAULT_CONNECT_REQUEST_TIMEOUT_MILLIS = 1000;
|
||||
@Value("${chenfeng.encrypt.publicKey:}")
|
||||
private String publicKey;
|
||||
|
||||
/**
|
||||
* 同步方式
|
||||
*
|
||||
*/
|
||||
@Bean
|
||||
public ElasticsearchClient elasticsearchClient(EsProperties properties) {
|
||||
return new ElasticsearchClient(getTransport(properties.getUris()));
|
||||
public ElasticsearchClient elasticsearchClient(RestClientTransport transport) {
|
||||
return new ElasticsearchClient(transport);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,44 +67,110 @@ public class ChenfengElasticsearchAutoConfiguration {
|
||||
*
|
||||
*/
|
||||
@Bean
|
||||
public ElasticsearchAsyncClient elasticsearchAsyncClient(EsProperties properties) {
|
||||
return new ElasticsearchAsyncClient(getTransport(properties.getUris()));
|
||||
public ElasticsearchAsyncClient elasticsearchAsyncClient(RestClientTransport transport) {
|
||||
return new ElasticsearchAsyncClient(transport);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
private ESDocumentService esDocumentService(ElasticsearchClient elasticsearchClient, ElasticsearchAsyncClient elasticsearchAsyncClient) {
|
||||
public ESDocumentService esDocumentService(ElasticsearchClient elasticsearchClient, ElasticsearchAsyncClient elasticsearchAsyncClient) {
|
||||
return new ESDocumentServiceImpl(elasticsearchClient, elasticsearchAsyncClient);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端 RestClientTransport
|
||||
*/
|
||||
private RestClientTransport getTransport(String hosts){
|
||||
HttpHost[] httpHosts = toHttpHost(hosts);
|
||||
RestClient restClient = getRestClient(httpHosts);
|
||||
return new RestClientTransport(restClient, new JacksonJsonpMapper());
|
||||
@Bean
|
||||
public RestClientTransport getTransport(RestClient client){
|
||||
return new RestClientTransport(client, new JacksonJsonpMapper());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取客户端RestClient
|
||||
* @param httpHosts http数组
|
||||
* chenfeng.encrypt.enable:true
|
||||
*
|
||||
* @param properties es配置
|
||||
*/
|
||||
private RestClient getRestClient(HttpHost[] httpHosts){
|
||||
return RestClient.builder(httpHosts).setRequestConfigCallback(requestConfigBuilder -> {
|
||||
requestConfigBuilder.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS);
|
||||
requestConfigBuilder.setSocketTimeout(DEFAULT_SOCKET_TIMEOUT_MILLIS);
|
||||
requestConfigBuilder.setConnectionRequestTimeout(DEFAULT_CONNECT_REQUEST_TIMEOUT_MILLIS);
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public RestClient getAuthRestClient(EsProperties properties) {
|
||||
// 配置账号密码
|
||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||
new UsernamePasswordCredentials(AesUtils.decrypt(properties.getUsername(), publicKey), AesUtils.decrypt(properties.getPassword(), publicKey)));
|
||||
RestClientBuilder.HttpClientConfigCallback httpClientConfigCallback = httpClientBuilder -> {
|
||||
// 设置账号密码、连接信息
|
||||
HttpAsyncClientBuilder httpAsyncClientBuilder = httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
|
||||
.setDefaultRequestConfig(RequestConfig.custom()
|
||||
.setConnectTimeout(properties.getConnectionTimeout().toSecondsPart())
|
||||
.setSocketTimeout(properties.getSocketTimeout().toSecondsPart())
|
||||
.setConnectionRequestTimeout(properties.getConnectionRequestTimeout().toSecondsPart())
|
||||
.build());
|
||||
if (properties.isSecurityHttpSslEnable()) {
|
||||
// 开启ssl配置连接证书
|
||||
httpAsyncClientBuilder.setSSLContext(buildSSLContext()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
|
||||
}
|
||||
return httpAsyncClientBuilder;
|
||||
};
|
||||
return RestClient.builder(toHttpHost(properties.getUris(), properties.isSecurityHttpSslEnable())).setHttpClientConfigCallback(httpClientConfigCallback).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端RestClient(默认)
|
||||
* chenfeng.encrypt.enable:false或者缺省
|
||||
*
|
||||
* @param properties es配置
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "false", matchIfMissing = true)
|
||||
public RestClient getRestClient(EsProperties properties) {
|
||||
return RestClient.builder(toHttpHost(properties.getUris(), properties.isSecurityHttpSslEnable())).setRequestConfigCallback(requestConfigBuilder -> {
|
||||
requestConfigBuilder.setConnectTimeout(properties.getConnectionTimeout().toSecondsPart());
|
||||
requestConfigBuilder.setSocketTimeout(properties.getSocketTimeout().toSecondsPart());
|
||||
requestConfigBuilder.setConnectionRequestTimeout(properties.getConnectionRequestTimeout().toSecondsPart());
|
||||
return requestConfigBuilder;
|
||||
}).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析配置的字符串hosts,转为HttpHost对象数组
|
||||
* 构建ssl请求信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private HttpHost[] toHttpHost(String hosts) {
|
||||
private SSLContext buildSSLContext() {
|
||||
SSLContext sslContext = null;
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource("http_ca.crt");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析域名
|
||||
*
|
||||
* @param hosts 域名字符串
|
||||
* @param isSslEnable 是否开启ssl
|
||||
* @return
|
||||
*/
|
||||
private HttpHost[] toHttpHost(String hosts, boolean isSslEnable) {
|
||||
if (!StringUtils.hasLength(hosts)) {
|
||||
throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
|
||||
throw new IllegalArgumentException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
|
||||
}
|
||||
// 多个IP逗号隔开
|
||||
String[] hostArray = hosts.split(",");
|
||||
@@ -87,14 +178,9 @@ public class ChenfengElasticsearchAutoConfiguration {
|
||||
HttpHost httpHost;
|
||||
for (int i = 0; i < hostArray.length; i++) {
|
||||
String[] strings = hostArray[i].split(":");
|
||||
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
|
||||
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), isSslEnable ? "https" : "http");
|
||||
httpHosts[i] = httpHost;
|
||||
}
|
||||
|
||||
return httpHosts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+89
-1
@@ -2,12 +2,46 @@ package com.cf.imes.framework.es.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* es环境配置
|
||||
* @author there
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.elasticsearch")
|
||||
public class EsProperties {
|
||||
private String uris;
|
||||
|
||||
/**
|
||||
* Username for authentication with Elasticsearch.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Password for authentication with Elasticsearch.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Connection timeout used when communicating with Elasticsearch.
|
||||
*/
|
||||
private Duration connectionTimeout = Duration.ofSeconds(10);
|
||||
|
||||
/**
|
||||
* Socket timeout used when communicating with Elasticsearch.
|
||||
*/
|
||||
private Duration socketTimeout = Duration.ofSeconds(30);
|
||||
|
||||
|
||||
private Duration connectionRequestTimeout = Duration.ofSeconds(1);
|
||||
|
||||
/**
|
||||
* Prefix added to the path of every request sent to Elasticsearch.
|
||||
*/
|
||||
private String pathPrefix;
|
||||
|
||||
private boolean securityHttpSslEnable = false;
|
||||
|
||||
public String getUris() {
|
||||
return uris;
|
||||
}
|
||||
@@ -16,5 +50,59 @@ public class EsProperties {
|
||||
this.uris = uris;
|
||||
}
|
||||
|
||||
private String uris;
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Duration getConnectionTimeout() {
|
||||
return this.connectionTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(Duration connectionTimeout) {
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
|
||||
public Duration getSocketTimeout() {
|
||||
return this.socketTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(Duration socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
public String getPathPrefix() {
|
||||
return this.pathPrefix;
|
||||
}
|
||||
|
||||
public void setPathPrefix(String pathPrefix) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
}
|
||||
|
||||
public boolean isSecurityHttpSslEnable() {
|
||||
return securityHttpSslEnable;
|
||||
}
|
||||
|
||||
public void setSecurityHttpSslEnable(boolean securityHttpSslEnable) {
|
||||
this.securityHttpSslEnable = securityHttpSslEnable;
|
||||
}
|
||||
|
||||
public Duration getConnectionRequestTimeout() {
|
||||
return connectionRequestTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionRequestTimeout(Duration connectionRequestTimeout) {
|
||||
this.connectionRequestTimeout = connectionRequestTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,9 +15,9 @@ import org.springframework.context.annotation.Bean;
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@AutoConfigureBefore(DynamicDataSourceAutoConfiguration.class)
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public class ChenfengDataSourceEncryptConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public DataSourceInitEvent getDataSourceInitEvent() {
|
||||
return new ChenfengDataSourceEncryptInitEvent();
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,13 +20,13 @@ import org.springframework.util.StringUtils;
|
||||
* @since 2024/8/27 9:46
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public class ChenfengRedisEncryptAutoConfiguration {
|
||||
|
||||
@Value("${chenfeng.encrypt.publicKey:}")
|
||||
private String publicKey;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||
public RedissonAutoConfigurationCustomizer redissonAutoConfigurationCustomizer() {
|
||||
return configuration -> {
|
||||
Config redissonConfig = new Config();
|
||||
|
||||
Reference in New Issue
Block a user