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.elasticsearch.ElasticsearchClient;
|
||||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||||
import co.elastic.clients.transport.rest_client.RestClientTransport;
|
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.ESDocumentService;
|
||||||
import com.cf.imes.framework.es.core.service.ESDocumentServiceImpl;
|
import com.cf.imes.framework.es.core.service.ESDocumentServiceImpl;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.http.HttpHost;
|
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.RestClient;
|
||||||
|
import org.elasticsearch.client.RestClientBuilder;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.util.StringUtils;
|
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
|
* @author there
|
||||||
@@ -21,20 +47,19 @@ import org.springframework.util.StringUtils;
|
|||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@ConditionalOnClass(ElasticsearchClient.class)
|
@ConditionalOnClass(ElasticsearchClient.class)
|
||||||
@EnableConfigurationProperties(EsProperties.class)
|
@EnableConfigurationProperties(EsProperties.class)
|
||||||
|
@Slf4j
|
||||||
public class ChenfengElasticsearchAutoConfiguration {
|
public class ChenfengElasticsearchAutoConfiguration {
|
||||||
|
|
||||||
//超时时间设置
|
@Value("${chenfeng.encrypt.publicKey:}")
|
||||||
public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 10000;
|
private String publicKey;
|
||||||
public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 300000;
|
|
||||||
public static final int DEFAULT_CONNECT_REQUEST_TIMEOUT_MILLIS = 1000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同步方式
|
* 同步方式
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public ElasticsearchClient elasticsearchClient(EsProperties properties) {
|
public ElasticsearchClient elasticsearchClient(RestClientTransport transport) {
|
||||||
return new ElasticsearchClient(getTransport(properties.getUris()));
|
return new ElasticsearchClient(transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,44 +67,110 @@ public class ChenfengElasticsearchAutoConfiguration {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public ElasticsearchAsyncClient elasticsearchAsyncClient(EsProperties properties) {
|
public ElasticsearchAsyncClient elasticsearchAsyncClient(RestClientTransport transport) {
|
||||||
return new ElasticsearchAsyncClient(getTransport(properties.getUris()));
|
return new ElasticsearchAsyncClient(transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
private ESDocumentService esDocumentService(ElasticsearchClient elasticsearchClient, ElasticsearchAsyncClient elasticsearchAsyncClient) {
|
public ESDocumentService esDocumentService(ElasticsearchClient elasticsearchClient, ElasticsearchAsyncClient elasticsearchAsyncClient) {
|
||||||
return new ESDocumentServiceImpl(elasticsearchClient, elasticsearchAsyncClient);
|
return new ESDocumentServiceImpl(elasticsearchClient, elasticsearchAsyncClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取客户端 RestClientTransport
|
* 获取客户端 RestClientTransport
|
||||||
*/
|
*/
|
||||||
private RestClientTransport getTransport(String hosts){
|
@Bean
|
||||||
HttpHost[] httpHosts = toHttpHost(hosts);
|
public RestClientTransport getTransport(RestClient client){
|
||||||
RestClient restClient = getRestClient(httpHosts);
|
return new RestClientTransport(client, new JacksonJsonpMapper());
|
||||||
return new RestClientTransport(restClient, new JacksonJsonpMapper());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取客户端RestClient
|
* 获取客户端RestClient
|
||||||
* @param httpHosts http数组
|
* chenfeng.encrypt.enable:true
|
||||||
|
*
|
||||||
|
* @param properties es配置
|
||||||
*/
|
*/
|
||||||
private RestClient getRestClient(HttpHost[] httpHosts){
|
@Bean
|
||||||
return RestClient.builder(httpHosts).setRequestConfigCallback(requestConfigBuilder -> {
|
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||||
requestConfigBuilder.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS);
|
public RestClient getAuthRestClient(EsProperties properties) {
|
||||||
requestConfigBuilder.setSocketTimeout(DEFAULT_SOCKET_TIMEOUT_MILLIS);
|
// 配置账号密码
|
||||||
requestConfigBuilder.setConnectionRequestTimeout(DEFAULT_CONNECT_REQUEST_TIMEOUT_MILLIS);
|
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;
|
return requestConfigBuilder;
|
||||||
}).build();
|
}).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)) {
|
if (!StringUtils.hasLength(hosts)) {
|
||||||
throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
|
throw new IllegalArgumentException("invalid elasticsearch configuration. elasticsearch.hosts不能为空!");
|
||||||
}
|
}
|
||||||
// 多个IP逗号隔开
|
// 多个IP逗号隔开
|
||||||
String[] hostArray = hosts.split(",");
|
String[] hostArray = hosts.split(",");
|
||||||
@@ -87,14 +178,9 @@ public class ChenfengElasticsearchAutoConfiguration {
|
|||||||
HttpHost httpHost;
|
HttpHost httpHost;
|
||||||
for (int i = 0; i < hostArray.length; i++) {
|
for (int i = 0; i < hostArray.length; i++) {
|
||||||
String[] strings = hostArray[i].split(":");
|
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;
|
httpHosts[i] = httpHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
return httpHosts;
|
return httpHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+89
-1
@@ -2,12 +2,46 @@ package com.cf.imes.framework.es.config;
|
|||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* es环境配置
|
* es环境配置
|
||||||
* @author there
|
* @author there
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "spring.elasticsearch")
|
@ConfigurationProperties(prefix = "spring.elasticsearch")
|
||||||
public class EsProperties {
|
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() {
|
public String getUris() {
|
||||||
return uris;
|
return uris;
|
||||||
}
|
}
|
||||||
@@ -16,5 +50,59 @@ public class EsProperties {
|
|||||||
this.uris = uris;
|
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
|
@AutoConfiguration
|
||||||
@AutoConfigureBefore(DynamicDataSourceAutoConfiguration.class)
|
@AutoConfigureBefore(DynamicDataSourceAutoConfiguration.class)
|
||||||
|
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||||
public class ChenfengDataSourceEncryptConfiguration {
|
public class ChenfengDataSourceEncryptConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
|
||||||
public DataSourceInitEvent getDataSourceInitEvent() {
|
public DataSourceInitEvent getDataSourceInitEvent() {
|
||||||
return new ChenfengDataSourceEncryptInitEvent();
|
return new ChenfengDataSourceEncryptInitEvent();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -20,13 +20,13 @@ import org.springframework.util.StringUtils;
|
|||||||
* @since 2024/8/27 9:46
|
* @since 2024/8/27 9:46
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
|
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
||||||
public class ChenfengRedisEncryptAutoConfiguration {
|
public class ChenfengRedisEncryptAutoConfiguration {
|
||||||
|
|
||||||
@Value("${chenfeng.encrypt.publicKey:}")
|
@Value("${chenfeng.encrypt.publicKey:}")
|
||||||
private String publicKey;
|
private String publicKey;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(name = "chenfeng.encrypt.enable", havingValue = "true")
|
|
||||||
public RedissonAutoConfigurationCustomizer redissonAutoConfigurationCustomizer() {
|
public RedissonAutoConfigurationCustomizer redissonAutoConfigurationCustomizer() {
|
||||||
return configuration -> {
|
return configuration -> {
|
||||||
Config redissonConfig = new Config();
|
Config redissonConfig = new Config();
|
||||||
|
|||||||
@@ -157,5 +157,7 @@ chenfeng:
|
|||||||
- infra_job_log
|
- infra_job_log
|
||||||
- infra_job_log
|
- infra_job_log
|
||||||
- infra_data_source_config
|
- infra_data_source_config
|
||||||
|
encrypt:
|
||||||
|
enable: false
|
||||||
|
publicKey: cfimes
|
||||||
debug: false
|
debug: false
|
||||||
|
|||||||
@@ -161,5 +161,7 @@ chenfeng:
|
|||||||
send-maximum-quantity-per-day: 10
|
send-maximum-quantity-per-day: 10
|
||||||
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
|
encrypt:
|
||||||
|
enable: false
|
||||||
|
publicKey: cfimes
|
||||||
debug: false
|
debug: false
|
||||||
|
|||||||
@@ -175,5 +175,7 @@ chenfeng:
|
|||||||
send-maximum-quantity-per-day: 10
|
send-maximum-quantity-per-day: 10
|
||||||
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
|
||||||
|
encrypt:
|
||||||
|
enable: false
|
||||||
|
publicKey: cfimes
|
||||||
debug: false
|
debug: false
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ chenfeng:
|
|||||||
organ: # 多租户相关配置项
|
organ: # 多租户相关配置项
|
||||||
enable: true
|
enable: true
|
||||||
ignore-tables:
|
ignore-tables:
|
||||||
|
encrypt:
|
||||||
|
enable: false
|
||||||
|
publicKey: cfimes
|
||||||
|
|
||||||
debug: false
|
debug: false
|
||||||
|
|||||||
Reference in New Issue
Block a user