mirror of
https://gitee.com/dromara/easy-es.git
synced 2025-12-06 17:18:57 +08:00
feat: 对于springboot和solon的适配调整
This commit is contained in:
parent
c23ea6b136
commit
8176c53a78
@ -20,7 +20,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-core</artifactId>
|
||||
<artifactId>easy-es-spring</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
package org.dromara.easyes.starter;
|
||||
|
||||
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.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.dromara.easyes.common.enums.SchemaEnum;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.core.service.AutoProcessIndexService;
|
||||
import org.dromara.easyes.spring.factory.IndexStrategyFactory;
|
||||
import org.dromara.easyes.spring.index.AutoProcessIndexNotSmoothlyServiceImpl;
|
||||
import org.dromara.easyes.spring.index.AutoProcessIndexSmoothlyServiceImpl;
|
||||
import org.dromara.easyes.common.property.EasyEsDynamicProperties;
|
||||
import org.dromara.easyes.common.property.EasyEsProperties;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.util.*;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
|
||||
/**
|
||||
* es自动配置
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Configuration
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class EsAutoConfiguration {
|
||||
|
||||
/**
|
||||
* 装配RestHighLevelClient
|
||||
*
|
||||
* @return RestHighLevelClient bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RestHighLevelClient restHighLevelClient() {
|
||||
return RestHighLevelClientUtils.restHighLevelClient(easyEsProperties());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "easy-es")
|
||||
public EasyEsProperties easyEsProperties() {
|
||||
return new EasyEsProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "easy-es.dynamic")
|
||||
public EasyEsDynamicProperties easyEsDynamicProperties() {
|
||||
return new EasyEsDynamicProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IndexStrategyFactory indexStrategyFactory() {
|
||||
return new IndexStrategyFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AutoProcessIndexService autoProcessIndexSmoothlyServiceImpl() {
|
||||
return new AutoProcessIndexSmoothlyServiceImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AutoProcessIndexService autoProcessIndexNotSmoothlyServiceImpl() {
|
||||
return new AutoProcessIndexNotSmoothlyServiceImpl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
package org.dromara.easyes.starter.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lyy
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "easy-es.dynamic")
|
||||
public class DynamicEsProperties {
|
||||
|
||||
/**
|
||||
* 配置多动态数据源key datasource id
|
||||
*/
|
||||
private Map<String, EasyEsConfigProperties> datasource = new HashMap<>();
|
||||
}
|
||||
@ -1,138 +0,0 @@
|
||||
package org.dromara.easyes.starter.config;
|
||||
|
||||
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.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.dromara.easyes.common.enums.SchemaEnum;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.util.*;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
import static org.dromara.easyes.common.utils.RestHighLevelClientUtils.DEFAULT_DS;
|
||||
|
||||
/**
|
||||
* es自动配置
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Configuration
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@EnableConfigurationProperties(value = {DynamicEsProperties.class, EasyEsConfigProperties.class})
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class EsAutoConfiguration {
|
||||
@Autowired
|
||||
private EasyEsConfigProperties easyEsConfigProperties;
|
||||
@Autowired
|
||||
private DynamicEsProperties dynamicEsProperties;
|
||||
|
||||
/**
|
||||
* 装配RestHighLevelClient
|
||||
*
|
||||
* @return RestHighLevelClient bean
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RestHighLevelClient restHighLevelClient() {
|
||||
return restHighLevelClient(easyEsConfigProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestHighLevelClientUtils restHighLevelClientUtils() {
|
||||
RestHighLevelClientUtils restHighLevelClientUtils = new RestHighLevelClientUtils();
|
||||
Map<String, EasyEsConfigProperties> datasourceMap = dynamicEsProperties.getDatasource();
|
||||
if (CollectionUtils.isEmpty(datasourceMap)) {
|
||||
// 设置默认数据源,兼容不使用多数据源配置场景的老用户使用习惯
|
||||
datasourceMap.put(DEFAULT_DS, easyEsConfigProperties);
|
||||
}
|
||||
for (String key : datasourceMap.keySet()) {
|
||||
EasyEsConfigProperties easyEsConfigProperties = datasourceMap.get(key);
|
||||
RestHighLevelClientUtils.registerRestHighLevelClient(key, restHighLevelClient(easyEsConfigProperties));
|
||||
}
|
||||
return restHighLevelClientUtils;
|
||||
}
|
||||
|
||||
|
||||
private RestHighLevelClient restHighLevelClient(EasyEsConfigProperties easyEsConfigProperties) {
|
||||
// 处理地址
|
||||
String address = easyEsConfigProperties.getAddress();
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
throw ExceptionUtils.eee("please config the es address");
|
||||
}
|
||||
if (!address.contains(COLON)) {
|
||||
throw ExceptionUtils.eee("the address must contains port and separate by ':'");
|
||||
}
|
||||
String schema = StringUtils.isEmpty(easyEsConfigProperties.getSchema())
|
||||
? DEFAULT_SCHEMA : easyEsConfigProperties.getSchema();
|
||||
List<HttpHost> hostList = new ArrayList<>();
|
||||
Arrays.stream(easyEsConfigProperties.getAddress().split(COMMA))
|
||||
.forEach(item -> hostList.add(new HttpHost(item.split(COLON)[0],
|
||||
Integer.parseInt(item.split(COLON)[1]), schema)));
|
||||
|
||||
// 转换成 HttpHost 数组
|
||||
HttpHost[] httpHost = hostList.toArray(new HttpHost[]{});
|
||||
|
||||
// 构建连接对象
|
||||
RestClientBuilder builder = RestClient.builder(httpHost);
|
||||
builder.setHttpClientConfigCallback(httpClientBuilder -> {
|
||||
// 设置心跳时间,最大连接数,最大连接路由
|
||||
Optional.ofNullable(easyEsConfigProperties.getKeepAliveMillis()).ifPresent(p -> httpClientBuilder.setKeepAliveStrategy((response, context) -> p));
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnTotal()).ifPresent(httpClientBuilder::setMaxConnTotal);
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnPerRoute()).ifPresent(httpClientBuilder::setMaxConnPerRoute);
|
||||
|
||||
// 设置账号密码
|
||||
String username = easyEsConfigProperties.getUsername();
|
||||
String password = easyEsConfigProperties.getPassword();
|
||||
if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)) {
|
||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||
new UsernamePasswordCredentials(username, password));
|
||||
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
|
||||
}
|
||||
|
||||
// https ssl ignore
|
||||
if (SchemaEnum.https.name().equals(schema)) {
|
||||
try {
|
||||
// 信任所有
|
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
|
||||
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||
httpClientBuilder.disableAuthCaching();
|
||||
httpClientBuilder.setSSLStrategy(sessionStrategy);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("restHighLevelClient build SSLContext exception: %s", e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw ExceptionUtils.eee(e);
|
||||
}
|
||||
}
|
||||
return httpClientBuilder;
|
||||
});
|
||||
|
||||
// 设置超时时间之类的
|
||||
builder.setRequestConfigCallback(requestConfigBuilder -> {
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectTimeout()).ifPresent(requestConfigBuilder::setConnectTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getSocketTimeout()).ifPresent(requestConfigBuilder::setSocketTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectionRequestTimeout())
|
||||
.ifPresent(requestConfigBuilder::setConnectionRequestTimeout);
|
||||
return requestConfigBuilder;
|
||||
});
|
||||
return new RestHighLevelClient(builder);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
package org.dromara.easyes.starter.factory;
|
||||
|
||||
|
||||
import org.dromara.easyes.starter.config.EasyEsConfigProperties;
|
||||
import org.dromara.easyes.starter.service.AutoProcessIndexService;
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.utils.ExceptionUtils;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 自动托管索引策略工厂
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Component
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class IndexStrategyFactory implements ApplicationContextAware, InitializingBean {
|
||||
/**
|
||||
* 配置
|
||||
*/
|
||||
@Autowired
|
||||
private EasyEsConfigProperties esConfigProperties;
|
||||
/**
|
||||
* 预估初始策略工厂容量
|
||||
*/
|
||||
private static final Integer DEFAULT_SIZE = 4;
|
||||
/**
|
||||
* spring上下文
|
||||
*/
|
||||
private ApplicationContext applicationContext;
|
||||
/**
|
||||
* 策略容器
|
||||
*/
|
||||
private static final Map<Integer, AutoProcessIndexService> SERVICE_MAP = new HashMap<>(DEFAULT_SIZE);
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
// 是否开启自动托管模式,默认开启
|
||||
if (!ProcessIndexStrategyEnum.MANUAL.equals(esConfigProperties.getGlobalConfig().getProcessIndexMode())) {
|
||||
// 将bean注册进工厂
|
||||
applicationContext.getBeansOfType(AutoProcessIndexService.class)
|
||||
.values()
|
||||
.forEach(v -> SERVICE_MAP.putIfAbsent(v.getStrategyType(), v));
|
||||
}
|
||||
}
|
||||
|
||||
public AutoProcessIndexService getByStrategyType(Integer strategyType) {
|
||||
return Optional.ofNullable(SERVICE_MAP.get(strategyType))
|
||||
.orElseThrow(() -> ExceptionUtils.eee("no such service strategyType:{}", strategyType));
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
package org.dromara.easyes.starter.register;
|
||||
|
||||
import org.dromara.easyes.core.kernel.BaseEsMapper;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 扫描指定路径下的所有接口
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
|
||||
public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
|
||||
super(registry, false);
|
||||
}
|
||||
|
||||
public void registerFilters() {
|
||||
// default include filter that accepts all classes
|
||||
addIncludeFilter((metadataReader, metadataReaderFactory) -> {
|
||||
// 跳过非ee的mapper,比如瞎几把写的接口,没有继承BaseEsMapper
|
||||
String className = metadataReader.getClassMetadata().getClassName();
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
return BaseEsMapper.class.isAssignableFrom(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.debug("mapper not found" + e);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// exclude package-info.java
|
||||
addExcludeFilter((metadataReader, metadataReaderFactory) -> {
|
||||
String className = metadataReader.getClassMetadata().getClassName();
|
||||
return className.endsWith("package-info");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
|
||||
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
|
||||
if (beanDefinitions.isEmpty()) {
|
||||
logger.warn("No Easy-Es mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
|
||||
} else {
|
||||
processBeanDefinitions(beanDefinitions);
|
||||
}
|
||||
return beanDefinitions;
|
||||
}
|
||||
|
||||
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
|
||||
GenericBeanDefinition definition;
|
||||
for (BeanDefinitionHolder holder : beanDefinitions) {
|
||||
definition = (GenericBeanDefinition) holder.getBeanDefinition();
|
||||
String beanClassName = definition.getBeanClassName();
|
||||
logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName()
|
||||
+ "' and '" + beanClassName + "' mapperInterface");
|
||||
|
||||
// the mapper interface is the original class of the bean
|
||||
// but, the actual class of the bean is MapperFactoryBean
|
||||
definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
|
||||
definition.setBeanClass(MapperFactoryBean.class);
|
||||
|
||||
logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
|
||||
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
|
||||
return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) {
|
||||
if (super.checkCandidate(beanName, beanDefinition)) {
|
||||
return true;
|
||||
} else {
|
||||
logger.warn("Skipping MapperFactoryBean with name '" + beanName
|
||||
+ "' and '" + beanDefinition.getBeanClassName() + "' mapperInterface"
|
||||
+ ". Bean already defined with the same name!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package org.dromara.easyes.starter.register;
|
||||
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 全局Mapper扫描注解
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Import(MapperScannerRegister.class)
|
||||
public @interface EsMapperScan {
|
||||
String value();
|
||||
}
|
||||
@ -1,129 +0,0 @@
|
||||
package org.dromara.easyes.starter.register;
|
||||
|
||||
import org.dromara.easyes.annotation.EsDS;
|
||||
import org.dromara.easyes.annotation.Intercepts;
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.utils.LogUtils;
|
||||
import org.dromara.easyes.common.utils.RestHighLevelClientUtils;
|
||||
import org.dromara.easyes.common.utils.TypeUtils;
|
||||
import org.dromara.easyes.core.biz.EntityInfo;
|
||||
import org.dromara.easyes.core.cache.BaseCache;
|
||||
import org.dromara.easyes.core.cache.GlobalConfigCache;
|
||||
import org.dromara.easyes.common.property.GlobalConfig;
|
||||
import org.dromara.easyes.core.proxy.EsMapperProxy;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.extension.context.Interceptor;
|
||||
import org.dromara.easyes.extension.context.InterceptorChain;
|
||||
import org.dromara.easyes.extension.context.InterceptorChainHolder;
|
||||
import org.dromara.easyes.starter.config.EasyEsConfigProperties;
|
||||
import org.dromara.easyes.starter.factory.IndexStrategyFactory;
|
||||
import org.dromara.easyes.starter.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.ZERO;
|
||||
import static org.dromara.easyes.common.utils.RestHighLevelClientUtils.DEFAULT_DS;
|
||||
|
||||
/**
|
||||
* 代理类
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public class MapperFactoryBean<T> implements FactoryBean<T> {
|
||||
private Class<T> mapperInterface;
|
||||
|
||||
@Autowired
|
||||
private RestHighLevelClientUtils restHighLevelClientUtils;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private IndexStrategyFactory indexStrategyFactory;
|
||||
|
||||
@Autowired
|
||||
private EasyEsConfigProperties esConfigProperties;
|
||||
|
||||
public MapperFactoryBean() {
|
||||
}
|
||||
|
||||
public MapperFactoryBean(Class<T> mapperInterface) {
|
||||
this.mapperInterface = mapperInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getObject() throws Exception {
|
||||
|
||||
EsMapperProxy<T> esMapperProxy = new EsMapperProxy<>(mapperInterface, new ConcurrentHashMap<>());
|
||||
|
||||
// 获取实体类
|
||||
Class<?> entityClass = TypeUtils.getInterfaceT(mapperInterface, ZERO);
|
||||
|
||||
// 初始化缓存
|
||||
GlobalConfigCache.setGlobalConfig(esConfigProperties.getGlobalConfig());
|
||||
|
||||
//获取动态数据源 若未配置多数据源,则使用默认数据源
|
||||
String restHighLevelClientId = Optional.ofNullable(mapperInterface.getAnnotation(EsDS.class)).map(EsDS::value).orElse(DEFAULT_DS);
|
||||
RestHighLevelClient client = restHighLevelClientUtils.getClient(restHighLevelClientId);
|
||||
BaseCache.initCache(mapperInterface, entityClass, client);
|
||||
|
||||
// 创建代理
|
||||
T t = (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, esMapperProxy);
|
||||
|
||||
// 初始化拦截器链
|
||||
InterceptorChain interceptorChain = this.initInterceptorChain();
|
||||
|
||||
// 异步处理索引创建/更新/数据迁移等
|
||||
GlobalConfig globalConfig = esConfigProperties.getGlobalConfig();
|
||||
if (!ProcessIndexStrategyEnum.MANUAL.equals(globalConfig.getProcessIndexMode())) {
|
||||
// 父子类型,仅针对父类型创建索引,子类型不创建索引
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
boolean isChild = entityInfo.isChild();
|
||||
if (!isChild) {
|
||||
AutoProcessIndexService autoProcessIndexService = indexStrategyFactory
|
||||
.getByStrategyType(globalConfig.getProcessIndexMode().getStrategyType());
|
||||
autoProcessIndexService.processIndexAsync(entityClass, client);
|
||||
}
|
||||
} else {
|
||||
LogUtils.info("===> manual index mode activated");
|
||||
}
|
||||
return interceptorChain.pluginAll(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return this.mapperInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private InterceptorChain initInterceptorChain() {
|
||||
InterceptorChainHolder interceptorChainHolder = InterceptorChainHolder.getInstance();
|
||||
InterceptorChain interceptorChain = interceptorChainHolder.getInterceptorChain();
|
||||
if (interceptorChain == null) {
|
||||
synchronized (this) {
|
||||
interceptorChainHolder.initInterceptorChain();
|
||||
Map<String, Object> beansWithAnnotation = this.applicationContext.getBeansWithAnnotation(Intercepts.class);
|
||||
beansWithAnnotation.forEach((key, val) -> {
|
||||
if (val instanceof Interceptor) {
|
||||
Interceptor interceptor = (Interceptor) val;
|
||||
interceptorChainHolder.addInterceptor(interceptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return interceptorChainHolder.getInterceptorChain();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,137 +0,0 @@
|
||||
package org.dromara.easyes.starter.register;
|
||||
|
||||
import org.dromara.easyes.common.utils.EEVersionUtils;
|
||||
import org.dromara.easyes.common.utils.LogUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
|
||||
/**
|
||||
* 注册bean
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public class MapperScannerRegister implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
|
||||
private ResourceLoader resourceLoader;
|
||||
private Environment environment;
|
||||
|
||||
@Override
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
Boolean enable = Optional.ofNullable(environment.getProperty(ENABLE_PREFIX)).map(Boolean::parseBoolean).orElse(Boolean.TRUE);
|
||||
if (!enable) {
|
||||
LogUtils.info("===> Easy-Es is not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
//打印banner @author dazer007
|
||||
boolean banner = Optional.ofNullable(environment.getProperty(ENABLE_BANNER)).map(Boolean::parseBoolean).orElse(Boolean.TRUE);
|
||||
if (banner) {
|
||||
boolean iKunMode = Optional.ofNullable(environment.getProperty(ENABLE_I_KUN_MODE)).map(Boolean::parseBoolean).orElse(Boolean.FALSE);
|
||||
String versionStr = EEVersionUtils.getJarVersion(this.getClass());
|
||||
String wechatStr = ":: wechat :: 252645816, add and become muscle man! >";
|
||||
if (iKunMode) {
|
||||
System.out.println(" 鸡你太美\n" +
|
||||
" 鸡你实在太美\n" +
|
||||
" 鸡你是太美\n" +
|
||||
" 鸡你太美\n" +
|
||||
" 实在是太美鸡你\n" +
|
||||
" 鸡你 实在是太美鸡你 美\n" +
|
||||
" 鸡你 实在是太美鸡美 太美\n" +
|
||||
" 鸡你 实在是太美鸡美 太美\n" +
|
||||
" 鸡你 实在是太美鸡美 太美\n" +
|
||||
" 鸡你 鸡你实在是美太美 美蓝球球球\n" +
|
||||
"鸡 鸡 鸡你实在是太美 篮球篮球球球球\n" +
|
||||
" 鸡 鸡你太美裆鸡太啊 球球蓝篮球球\n" +
|
||||
" 鸡你太美裆裆鸡美 球球球\n" +
|
||||
" 鸡你裆小 j 鸡太美\n" +
|
||||
" 鸡太美 鸡太美\n" +
|
||||
" 鸡美 鸡美\n" +
|
||||
" 鸡美 鸡美\n" +
|
||||
" 鸡美 鸡美\n" +
|
||||
" 鸡太 鸡太\n" +
|
||||
" 鸡 脚 鸡脚\n" +
|
||||
" 皮 鞋 皮鞋金猴\n" +
|
||||
" 金光 金光 大道\n" +
|
||||
" 大道\n" +
|
||||
" 鸡神保佑 永不宕机 永无BUG");
|
||||
wechatStr = ":: wechat :: 252645816, add and join ikun(小黑子) group! >";
|
||||
} else {
|
||||
System.out.println("\n" +
|
||||
"___ _ _ ___\n" +
|
||||
" | __| __ _ ___ | || | ___ | __| ___\n" +
|
||||
" | _| / _` | (_-< \\_, | |___| | _| (_-<\n" +
|
||||
" |___| \\__,_| /__/_ _|__/ _____ |___| /__/_\n" +
|
||||
"_|\"\"\"\"\"|_|\"\"\"\"\"|_|\"\"\"\"\"|_| \"\"\"\"|_| |_|\"\"\"\"\"|_|\"\"\"\"\"|\n" +
|
||||
"\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\"`-0-0-'\n" +
|
||||
"----------------------------------------------------------->"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 版本长度并不固定,比如beta版,所以需要特殊处理
|
||||
int width = 43;
|
||||
int blank = width - versionStr.length();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(":: version :: ")
|
||||
.append(versionStr);
|
||||
for (int i = 0; i < blank; i++) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(">");
|
||||
if (iKunMode) {
|
||||
System.out.println("----------------------------------------------------------->");
|
||||
}
|
||||
System.out.println(":: project :: Easy-Es >");
|
||||
System.out.println(sb);
|
||||
System.out.println(":: home :: https://easy-es.cn/ >");
|
||||
System.out.println(":: community :: https://dromara.org/ >");
|
||||
System.out.println(wechatStr);
|
||||
System.out.println("----------------------------------------------------------->");
|
||||
}
|
||||
|
||||
AnnotationAttributes mapperScanAttrs = AnnotationAttributes
|
||||
.fromMap(importingClassMetadata.getAnnotationAttributes(EsMapperScan.class.getName()));
|
||||
if (mapperScanAttrs != null) {
|
||||
registerBeanDefinitions(mapperScanAttrs, registry);
|
||||
}
|
||||
}
|
||||
|
||||
void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry) {
|
||||
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
|
||||
// this check is needed in Spring 3.1
|
||||
Optional.ofNullable(resourceLoader).ifPresent(scanner::setResourceLoader);
|
||||
List<String> basePackages = new ArrayList<>();
|
||||
basePackages.addAll(
|
||||
Arrays.stream(annoAttrs.getStringArray("value"))
|
||||
.filter(StringUtils::hasText)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
scanner.registerFilters();
|
||||
scanner.doScan(StringUtils.toStringArray(basePackages));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package org.dromara.easyes.starter.service;
|
||||
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
|
||||
/**
|
||||
* 自动托管索引接口
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
public interface AutoProcessIndexService {
|
||||
/**
|
||||
* 获取当前策略类型
|
||||
*
|
||||
* @return 策略类型
|
||||
*/
|
||||
Integer getStrategyType();
|
||||
|
||||
/**
|
||||
* 异步处理索引
|
||||
*
|
||||
* @param entityClass 实体类
|
||||
* @param client restHighLevelClient
|
||||
*/
|
||||
void processIndexAsync(Class<?> entityClass, RestHighLevelClient client);
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
package org.dromara.easyes.starter.service.impl;
|
||||
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.utils.LogUtils;
|
||||
import org.dromara.easyes.core.biz.CreateIndexParam;
|
||||
import org.dromara.easyes.core.biz.EntityInfo;
|
||||
import org.dromara.easyes.core.biz.EsIndexInfo;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
import org.dromara.easyes.starter.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 自动非平滑托管索引实现类, 重建索引时原索引数据会被删除
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Service
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class AutoProcessIndexNotSmoothlyServiceImpl implements AutoProcessIndexService {
|
||||
|
||||
@Override
|
||||
public Integer getStrategyType() {
|
||||
return ProcessIndexStrategyEnum.NOT_SMOOTHLY.getStrategyType();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void processIndexAsync(Class<?> entityClass, RestHighLevelClient client) {
|
||||
LogUtils.info("===> Not smoothly process index mode activated");
|
||||
IndexUtils.supplyAsync(this::process, entityClass, client);
|
||||
}
|
||||
|
||||
private boolean process(Class<?> entityClass, RestHighLevelClient client) {
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
// 是否存在索引
|
||||
boolean existsIndex = IndexUtils.existsIndexWithRetry(entityInfo, client);
|
||||
if (existsIndex) {
|
||||
// 更新
|
||||
LogUtils.info("===> Index exists, automatically updating index by easy-es...");
|
||||
return doUpdateIndex(entityInfo, entityClass, client);
|
||||
} else {
|
||||
// 新建
|
||||
LogUtils.info("===> Index not exists, automatically creating index by easy-es...");
|
||||
return doCreateIndex(entityInfo, entityClass, client);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doUpdateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
|
||||
// 获取索引信息
|
||||
EsIndexInfo esIndexInfo = IndexUtils.getIndexInfo(client, entityInfo.getRetrySuccessIndexName());
|
||||
|
||||
// 索引是否有变化 若有则直接删除旧索引,创建新索引 若无则直接返回托管成功
|
||||
boolean isIndexNeedChange = IndexUtils.isIndexNeedChange(esIndexInfo, entityInfo, clazz);
|
||||
if (!isIndexNeedChange) {
|
||||
LogUtils.info("===> index has nothing changed");
|
||||
entityInfo.setIndexName(entityInfo.getRetrySuccessIndexName());
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
// 直接删除旧索引
|
||||
IndexUtils.deleteIndex(client, entityInfo.getRetrySuccessIndexName());
|
||||
|
||||
// 初始化创建索引参数
|
||||
CreateIndexParam createIndexParam = IndexUtils.getCreateIndexParam(entityInfo, clazz);
|
||||
|
||||
// 执行创建
|
||||
return IndexUtils.createIndex(client, entityInfo, createIndexParam);
|
||||
}
|
||||
|
||||
private boolean doCreateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
|
||||
// 初始化创建索引参数
|
||||
CreateIndexParam createIndexParam = IndexUtils.getCreateIndexParam(entityInfo, clazz);
|
||||
|
||||
// 执行创建
|
||||
return IndexUtils.createIndex(client, entityInfo, createIndexParam);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,136 +0,0 @@
|
||||
package org.dromara.easyes.starter.service.impl;
|
||||
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.utils.LogUtils;
|
||||
import org.dromara.easyes.core.biz.CreateIndexParam;
|
||||
import org.dromara.easyes.core.biz.EntityInfo;
|
||||
import org.dromara.easyes.core.biz.EsIndexInfo;
|
||||
import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.core.toolkit.IndexUtils;
|
||||
import org.dromara.easyes.starter.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.S1_SUFFIX;
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.SO_SUFFIX;
|
||||
|
||||
/**
|
||||
* 自动平滑托管索引实现类,本框架默认模式,过程零停机,数据会自动转移至新索引
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Service
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
@ConditionalOnExpression("'${easy-es.address:x}'!='x'")
|
||||
@ConditionalOnProperty(prefix = "easy-es", name = {"enable"}, havingValue = "true", matchIfMissing = true)
|
||||
public class AutoProcessIndexSmoothlyServiceImpl implements AutoProcessIndexService {
|
||||
@Override
|
||||
public Integer getStrategyType() {
|
||||
return ProcessIndexStrategyEnum.SMOOTHLY.getStrategyType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIndexAsync(Class<?> entityClass, RestHighLevelClient client) {
|
||||
LogUtils.info("===> Smoothly process index mode activated");
|
||||
IndexUtils.supplyAsync(this::process, entityClass, client);
|
||||
}
|
||||
|
||||
|
||||
private synchronized boolean process(Class<?> entityClass, RestHighLevelClient client) {
|
||||
EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(entityClass);
|
||||
|
||||
// 索引是否已存在
|
||||
boolean existsIndex = IndexUtils.existsIndexWithRetryAndSetActiveIndex(entityInfo, client);
|
||||
if (existsIndex) {
|
||||
// 更新
|
||||
LogUtils.info("===> Index exists, automatically updating index by easy-es...");
|
||||
return doUpdateIndex(entityInfo, entityClass, client);
|
||||
} else {
|
||||
// 新建
|
||||
LogUtils.info("===> Index not exists, automatically creating index by easy-es...");
|
||||
return doCreateIndex(entityInfo, entityClass, client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean doUpdateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
|
||||
// 获取索引信息
|
||||
EsIndexInfo esIndexInfo = IndexUtils.getIndexInfo(client, entityInfo.getIndexName());
|
||||
|
||||
// 是否存在默认别名,若无则给添加
|
||||
if (!esIndexInfo.getHasDefaultAlias()) {
|
||||
IndexUtils.addDefaultAlias(client, entityInfo.getIndexName());
|
||||
}
|
||||
|
||||
// 索引是否有变化 若有则创建新索引并无感迁移, 若无则直接返回托管成功
|
||||
boolean isIndexNeedChange = IndexUtils.isIndexNeedChange(esIndexInfo, entityInfo, clazz);
|
||||
if (!isIndexNeedChange) {
|
||||
LogUtils.info("===> index has nothing changed");
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
// 创建新索引
|
||||
String releaseIndexName = generateReleaseIndexName(entityInfo.getIndexName());
|
||||
entityInfo.setReleaseIndexName(releaseIndexName);
|
||||
boolean isCreateIndexSuccess = doCreateIndex(entityInfo, clazz, client);
|
||||
if (!isCreateIndexSuccess) {
|
||||
LogUtils.error("create release index failed", "releaseIndex:" + releaseIndexName);
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
// 迁移数据至新创建的索引
|
||||
boolean isDataMigrationSuccess = doDataMigration(entityInfo.getIndexName(), releaseIndexName, entityInfo.getMaxResultWindow(), client);
|
||||
if (!isDataMigrationSuccess) {
|
||||
LogUtils.error("migrate data failed", "oldIndex:" + entityInfo.getIndexName(), "releaseIndex:" + releaseIndexName);
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
// 原子操作 切换别名:将默认别名关联至新索引,并将旧索引的默认别名移除
|
||||
boolean isChangeAliasSuccess = IndexUtils.changeAliasAtomic(client, entityInfo.getIndexName(), releaseIndexName);
|
||||
if (!isChangeAliasSuccess) {
|
||||
LogUtils.error("change alias atomically failed", "oldIndex:" + entityInfo.getIndexName(), "releaseIndex:" + releaseIndexName);
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
// 删除旧索引
|
||||
boolean isDeletedIndexSuccess = IndexUtils.deleteIndex(client, entityInfo.getIndexName());
|
||||
if (!isDeletedIndexSuccess) {
|
||||
LogUtils.error("delete old index failed", "oldIndex:" + entityInfo.getIndexName());
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
// 用最新索引覆盖缓存中的老索引
|
||||
entityInfo.setIndexName(releaseIndexName);
|
||||
|
||||
// 将新索引名称记录至ee-distribute-lock索引中,以便在分布式环境下其它机器能够感知到
|
||||
IndexUtils.saveReleaseIndex(releaseIndexName, client);
|
||||
|
||||
// done.
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
private String generateReleaseIndexName(String oldIndexName) {
|
||||
if (oldIndexName.endsWith(SO_SUFFIX)) {
|
||||
return oldIndexName.split(SO_SUFFIX)[0] + S1_SUFFIX;
|
||||
} else if (oldIndexName.endsWith(S1_SUFFIX)) {
|
||||
return oldIndexName.split(S1_SUFFIX)[0] + SO_SUFFIX;
|
||||
} else {
|
||||
return oldIndexName + SO_SUFFIX;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doDataMigration(String oldIndexName, String releaseIndexName, Integer maxResultWindow, RestHighLevelClient client) {
|
||||
return IndexUtils.reindex(client, oldIndexName, releaseIndexName, maxResultWindow);
|
||||
}
|
||||
|
||||
private boolean doCreateIndex(EntityInfo entityInfo, Class<?> clazz, RestHighLevelClient client) {
|
||||
// 初始化创建索引参数
|
||||
CreateIndexParam createIndexParam = IndexUtils.getCreateIndexParam(entityInfo, clazz);
|
||||
// 执行创建
|
||||
return IndexUtils.createIndex(client, entityInfo, createIndexParam);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,7 +1,4 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.dromara.easyes.starter.config.EsAutoConfiguration,\
|
||||
org.dromara.easyes.starter.factory.IndexStrategyFactory,\
|
||||
org.dromara.easyes.starter.service.impl.AutoProcessIndexSmoothlyServiceImpl,\
|
||||
org.dromara.easyes.starter.service.impl.AutoProcessIndexNotSmoothlyServiceImpl,\
|
||||
org.dromara.easyes.starter.EsAutoConfiguration,\
|
||||
org.dromara.easyes.starter.config.GeneratorConfiguration
|
||||
|
||||
@ -1,5 +1 @@
|
||||
org.dromara.easyes.starter.config.EsAutoConfiguration
|
||||
org.dromara.easyes.starter.factory.IndexStrategyFactory
|
||||
org.dromara.easyes.starter.service.impl.AutoProcessIndexSmoothlyServiceImpl
|
||||
org.dromara.easyes.starter.service.impl.AutoProcessIndexNotSmoothlyServiceImpl
|
||||
org.dromara.easyes.starter.config.GeneratorConfiguration
|
||||
org.dromara.easyes.starter.EsAutoConfiguration
|
||||
@ -0,0 +1,21 @@
|
||||
package org.dromara.easyes.common.property;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* easy-es基础配置项 考虑到spring的场景,有些参数不是必须配置
|
||||
* 基本类型就会出现默认值的情况 所以为了要有null值出现,这里采用包装类型
|
||||
* <p>
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Data
|
||||
public class EasyEsDynamicProperties {
|
||||
|
||||
/**
|
||||
* 配置多动态数据源key datasource id
|
||||
*/
|
||||
private Map<String, EasyEsProperties> datasource = new HashMap<>();
|
||||
|
||||
}
|
||||
@ -1,11 +1,7 @@
|
||||
package org.dromara.easyes.solon.config;
|
||||
package org.dromara.easyes.common.property;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.easyes.common.enums.SchemaEnum;
|
||||
import org.dromara.easyes.common.property.GlobalConfig;
|
||||
import org.noear.solon.annotation.Condition;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
/**
|
||||
* easy-es基础配置项
|
||||
@ -13,10 +9,8 @@ import org.noear.solon.annotation.Inject;
|
||||
* Copyright © 2022 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Data
|
||||
@Configuration
|
||||
@Inject(value = "${easy-es}", autoRefreshed = true)
|
||||
@Condition(onProperty = "${easy-es.enable:true} = true && ${easy-es.address:x} != x")
|
||||
public class EasyEsConfigProperties {
|
||||
public class EasyEsProperties {
|
||||
|
||||
/**
|
||||
* 是否开启easy-es 默认开启
|
||||
*/
|
||||
@ -69,4 +63,5 @@ public class EasyEsConfigProperties {
|
||||
* global config 全局配置
|
||||
*/
|
||||
private GlobalConfig globalConfig = new GlobalConfig();
|
||||
|
||||
}
|
||||
@ -1,10 +1,27 @@
|
||||
package org.dromara.easyes.common.utils;
|
||||
|
||||
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.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.dromara.easyes.common.enums.SchemaEnum;
|
||||
import org.dromara.easyes.common.property.EasyEsProperties;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.COLON;
|
||||
|
||||
/**
|
||||
* @author lyy
|
||||
*/
|
||||
@ -40,4 +57,68 @@ public class RestHighLevelClientUtils {
|
||||
RestHighLevelClientUtils.restHighLevelClientMap.putIfAbsent(restHighLevelClientId, restHighLevelClient);
|
||||
}
|
||||
|
||||
public static RestHighLevelClient restHighLevelClient(EasyEsProperties easyEsConfigProperties) {
|
||||
// 处理地址
|
||||
String address = easyEsConfigProperties.getAddress();
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
throw ExceptionUtils.eee("please config the es address");
|
||||
}
|
||||
if (!address.contains(COLON)) {
|
||||
throw ExceptionUtils.eee("the address must contains port and separate by ':'");
|
||||
}
|
||||
String schema = StringUtils.isEmpty(easyEsConfigProperties.getSchema())
|
||||
? DEFAULT_SCHEMA : easyEsConfigProperties.getSchema();
|
||||
List<HttpHost> hostList = new ArrayList<>();
|
||||
Arrays.stream(easyEsConfigProperties.getAddress().split(COMMA))
|
||||
.forEach(item -> hostList.add(new HttpHost(item.split(COLON)[0],
|
||||
Integer.parseInt(item.split(COLON)[1]), schema)));
|
||||
|
||||
// 转换成 HttpHost 数组
|
||||
HttpHost[] httpHost = hostList.toArray(new HttpHost[]{});
|
||||
|
||||
// 构建连接对象
|
||||
RestClientBuilder builder = RestClient.builder(httpHost);
|
||||
builder.setHttpClientConfigCallback(httpClientBuilder -> {
|
||||
// 设置心跳时间,最大连接数,最大连接路由
|
||||
Optional.ofNullable(easyEsConfigProperties.getKeepAliveMillis()).ifPresent(p -> httpClientBuilder.setKeepAliveStrategy((response, context) -> p));
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnTotal()).ifPresent(httpClientBuilder::setMaxConnTotal);
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnPerRoute()).ifPresent(httpClientBuilder::setMaxConnPerRoute);
|
||||
|
||||
// 设置账号密码
|
||||
String username = easyEsConfigProperties.getUsername();
|
||||
String password = easyEsConfigProperties.getPassword();
|
||||
if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)) {
|
||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||
new UsernamePasswordCredentials(username, password));
|
||||
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
|
||||
}
|
||||
|
||||
// https ssl ignore
|
||||
if (SchemaEnum.https.name().equals(schema)) {
|
||||
try {
|
||||
// 信任所有
|
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
|
||||
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||
httpClientBuilder.disableAuthCaching();
|
||||
httpClientBuilder.setSSLStrategy(sessionStrategy);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("restHighLevelClient build SSLContext exception: %s", e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw ExceptionUtils.eee(e);
|
||||
}
|
||||
}
|
||||
return httpClientBuilder;
|
||||
});
|
||||
|
||||
// 设置超时时间之类的
|
||||
builder.setRequestConfigCallback(requestConfigBuilder -> {
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectTimeout()).ifPresent(requestConfigBuilder::setConnectTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getSocketTimeout()).ifPresent(requestConfigBuilder::setSocketTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectionRequestTimeout())
|
||||
.ifPresent(requestConfigBuilder::setConnectionRequestTimeout);
|
||||
return requestConfigBuilder;
|
||||
});
|
||||
return new RestHighLevelClient(builder);
|
||||
}
|
||||
}
|
||||
@ -69,6 +69,11 @@
|
||||
<artifactId>easy-es-annotation</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara.easy-es</groupId>
|
||||
<artifactId>easy-es-spring</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
package org.dromara.easyes.solon.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.noear.solon.annotation.Condition;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lyy
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@Inject(value = "${easy-es.dynamic}", autoRefreshed = true)
|
||||
public class DynamicEsProperties {
|
||||
|
||||
/**
|
||||
* 配置多动态数据源key datasource id
|
||||
*/
|
||||
private Map<String, EasyEsConfigProperties> datasource = new HashMap<>();
|
||||
}
|
||||
@ -1,30 +1,16 @@
|
||||
package org.dromara.easyes.solon.config;
|
||||
|
||||
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.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.dromara.easyes.common.enums.SchemaEnum;
|
||||
import org.dromara.easyes.common.property.EasyEsDynamicProperties;
|
||||
import org.dromara.easyes.common.property.EasyEsProperties;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Condition;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.util.*;
|
||||
|
||||
import static org.dromara.easyes.common.constants.BaseEsConstants.*;
|
||||
import static org.dromara.easyes.common.utils.RestHighLevelClientUtils.DEFAULT_DS;
|
||||
|
||||
/**
|
||||
* es自动配置
|
||||
* <p>
|
||||
@ -34,10 +20,17 @@ import static org.dromara.easyes.common.utils.RestHighLevelClientUtils.DEFAULT_D
|
||||
@Condition(onClass = RestHighLevelClient.class, onProperty = "${easy-es.enable:true} = true && ${easy-es.address:x} != x")
|
||||
public class EsAutoConfiguration {
|
||||
|
||||
@Inject
|
||||
private EasyEsConfigProperties easyEsConfigProperties;
|
||||
@Inject
|
||||
private DynamicEsProperties dynamicEsProperties;
|
||||
@Bean
|
||||
public EasyEsProperties easyEsProperties(
|
||||
@Inject(value = "${easy-es}", autoRefreshed = true) EasyEsProperties properties) {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EasyEsDynamicProperties easyEsDynamicProperties(
|
||||
@Inject(value = "${easy-es.dynamic}", autoRefreshed = true) EasyEsDynamicProperties dynamicProperties) {
|
||||
return dynamicProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 装配RestHighLevelClient
|
||||
@ -46,88 +39,25 @@ public class EsAutoConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
@Condition(onMissingBean = RestHighLevelClient.class)
|
||||
public RestHighLevelClient restHighLevelClient() {
|
||||
return restHighLevelClient(easyEsConfigProperties);
|
||||
public RestHighLevelClient restHighLevelClient(EasyEsProperties easyEsProperties) {
|
||||
return RestHighLevelClientUtils.restHighLevelClient(easyEsProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestHighLevelClientUtils restHighLevelClientUtils() {
|
||||
public RestHighLevelClientUtils restHighLevelClientUtils(
|
||||
EasyEsProperties properties, EasyEsDynamicProperties dynamicProperties) {
|
||||
RestHighLevelClientUtils restHighLevelClientUtils = new RestHighLevelClientUtils();
|
||||
Map<String, EasyEsConfigProperties> datasourceMap = dynamicEsProperties.getDatasource();
|
||||
Map<String, EasyEsProperties> datasourceMap = dynamicProperties.getDatasource();
|
||||
if (CollectionUtils.isEmpty(datasourceMap)) {
|
||||
// 设置默认数据源,兼容不使用多数据源配置场景的老用户使用习惯
|
||||
datasourceMap.put(DEFAULT_DS, easyEsConfigProperties);
|
||||
datasourceMap.put(RestHighLevelClientUtils.DEFAULT_DS, properties);
|
||||
}
|
||||
for (String key : datasourceMap.keySet()) {
|
||||
EasyEsConfigProperties easyEsConfigProperties = datasourceMap.get(key);
|
||||
RestHighLevelClientUtils.registerRestHighLevelClient(key, restHighLevelClient(easyEsConfigProperties));
|
||||
EasyEsProperties easyEsConfigProperties = datasourceMap.get(key);
|
||||
RestHighLevelClientUtils.registerRestHighLevelClient(key, RestHighLevelClientUtils
|
||||
.restHighLevelClient(easyEsConfigProperties));
|
||||
}
|
||||
return restHighLevelClientUtils;
|
||||
}
|
||||
|
||||
|
||||
private RestHighLevelClient restHighLevelClient(EasyEsConfigProperties easyEsConfigProperties) {
|
||||
// 处理地址
|
||||
String address = easyEsConfigProperties.getAddress();
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
throw ExceptionUtils.eee("please config the es address");
|
||||
}
|
||||
if (!address.contains(COLON)) {
|
||||
throw ExceptionUtils.eee("the address must contains port and separate by ':'");
|
||||
}
|
||||
String schema = StringUtils.isEmpty(easyEsConfigProperties.getSchema())
|
||||
? DEFAULT_SCHEMA : easyEsConfigProperties.getSchema();
|
||||
List<HttpHost> hostList = new ArrayList<>();
|
||||
Arrays.stream(easyEsConfigProperties.getAddress().split(COMMA))
|
||||
.forEach(item -> hostList.add(new HttpHost(item.split(COLON)[0],
|
||||
Integer.parseInt(item.split(COLON)[1]), schema)));
|
||||
|
||||
// 转换成 HttpHost 数组
|
||||
HttpHost[] httpHost = hostList.toArray(new HttpHost[]{});
|
||||
|
||||
// 构建连接对象
|
||||
RestClientBuilder builder = RestClient.builder(httpHost);
|
||||
builder.setHttpClientConfigCallback(httpClientBuilder -> {
|
||||
// 设置心跳时间,最大连接数,最大连接路由
|
||||
Optional.ofNullable(easyEsConfigProperties.getKeepAliveMillis()).ifPresent(p -> httpClientBuilder.setKeepAliveStrategy((response, context) -> p));
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnTotal()).ifPresent(httpClientBuilder::setMaxConnTotal);
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnPerRoute()).ifPresent(httpClientBuilder::setMaxConnPerRoute);
|
||||
|
||||
// 设置账号密码
|
||||
String username = easyEsConfigProperties.getUsername();
|
||||
String password = easyEsConfigProperties.getPassword();
|
||||
if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)) {
|
||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||
new UsernamePasswordCredentials(username, password));
|
||||
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
|
||||
}
|
||||
|
||||
// https ssl ignore
|
||||
if (SchemaEnum.https.name().equals(schema)) {
|
||||
try {
|
||||
// 信任所有
|
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
|
||||
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||
httpClientBuilder.disableAuthCaching();
|
||||
httpClientBuilder.setSSLStrategy(sessionStrategy);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("restHighLevelClient build SSLContext exception: %s", e.getMessage());
|
||||
throw ExceptionUtils.eee(e);
|
||||
}
|
||||
}
|
||||
return httpClientBuilder;
|
||||
});
|
||||
|
||||
// 设置超时时间之类的
|
||||
builder.setRequestConfigCallback(requestConfigBuilder -> {
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectTimeout()).ifPresent(requestConfigBuilder::setConnectTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getSocketTimeout()).ifPresent(requestConfigBuilder::setSocketTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectionRequestTimeout())
|
||||
.ifPresent(requestConfigBuilder::setConnectionRequestTimeout);
|
||||
return requestConfigBuilder;
|
||||
});
|
||||
return new RestHighLevelClient(builder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package org.dromara.easyes.solon.factory;
|
||||
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.property.EasyEsProperties;
|
||||
import org.dromara.easyes.common.utils.ExceptionUtils;
|
||||
import org.dromara.easyes.solon.config.EasyEsConfigProperties;
|
||||
import org.dromara.easyes.solon.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.noear.solon.Solon;
|
||||
@ -28,7 +28,7 @@ public class IndexStrategyFactory implements LifecycleBean {
|
||||
* 配置
|
||||
*/
|
||||
@Inject
|
||||
private EasyEsConfigProperties esConfigProperties;
|
||||
private EasyEsProperties esConfigProperties;
|
||||
/**
|
||||
* 预估初始策略工厂容量
|
||||
*/
|
||||
|
||||
@ -11,5 +11,5 @@ import java.lang.annotation.*;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface EsMapperScan {
|
||||
String value();
|
||||
String[] value();
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.dromara.easyes.solon.register;
|
||||
import org.dromara.easyes.annotation.EsDS;
|
||||
import org.dromara.easyes.annotation.Intercepts;
|
||||
import org.dromara.easyes.common.enums.ProcessIndexStrategyEnum;
|
||||
import org.dromara.easyes.common.property.EasyEsProperties;
|
||||
import org.dromara.easyes.common.utils.EEVersionUtils;
|
||||
import org.dromara.easyes.common.utils.LogUtils;
|
||||
import org.dromara.easyes.common.utils.RestHighLevelClientUtils;
|
||||
@ -17,7 +18,6 @@ import org.dromara.easyes.core.toolkit.EntityInfoHelper;
|
||||
import org.dromara.easyes.extension.context.Interceptor;
|
||||
import org.dromara.easyes.extension.context.InterceptorChain;
|
||||
import org.dromara.easyes.extension.context.InterceptorChainHolder;
|
||||
import org.dromara.easyes.solon.config.EasyEsConfigProperties;
|
||||
import org.dromara.easyes.solon.factory.IndexStrategyFactory;
|
||||
import org.dromara.easyes.solon.service.AutoProcessIndexService;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
@ -116,7 +116,8 @@ public class MapperScannerRegister implements BeanBuilder<EsMapperScan> {
|
||||
System.out.println("----------------------------------------------------------->");
|
||||
}
|
||||
// 查找es mapper
|
||||
Collection<Class<?>> classPath = ClassUtil.scanClasses(anno.value());
|
||||
for (String doScan : anno.value()) {
|
||||
Collection<Class<?>> classPath = ClassUtil.scanClasses(doScan);
|
||||
for (Class<?> clazz : classPath) {
|
||||
// 跳过非ee的mapper,比如瞎几把写的接口,没有继承BaseEsMapper,继承了的推入容器
|
||||
if (BaseEsMapper.class.isAssignableFrom(clazz)) {
|
||||
@ -125,13 +126,15 @@ public class MapperScannerRegister implements BeanBuilder<EsMapperScan> {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将mapper代理对象推入容器
|
||||
* @param clazz mapper
|
||||
* @author MoJie
|
||||
*/
|
||||
private void beanWrapPut(Class<?> clazz) {
|
||||
EasyEsConfigProperties esConfigProperties = context.getBean(EasyEsConfigProperties.class);
|
||||
EasyEsProperties esConfigProperties = context.getBean(EasyEsProperties.class);
|
||||
RestHighLevelClientUtils restHighLevelClientUtils = context.getBeanOrNew(RestHighLevelClientUtils.class);
|
||||
EsMapperProxy<?> esMapperProxy = new EsMapperProxy<>(clazz, new ConcurrentHashMap<>());
|
||||
// 获取实体类
|
||||
|
||||
@ -22,15 +22,13 @@ import java.util.Set;
|
||||
* <p>
|
||||
* Copyright © 2021 xpc1024 All Rights Reserved
|
||||
**/
|
||||
@Setter
|
||||
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
|
||||
|
||||
@Setter
|
||||
private IndexStrategyFactory indexStrategyFactory;
|
||||
|
||||
@Setter
|
||||
private RestHighLevelClientUtils restHighLevelClientUtils;
|
||||
|
||||
@Setter
|
||||
private GlobalConfig globalConfig;
|
||||
|
||||
public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
|
||||
|
||||
@ -13,7 +13,8 @@ import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.dromara.easyes.common.enums.SchemaEnum;
|
||||
import org.dromara.easyes.common.utils.*;
|
||||
import org.dromara.easyes.spring.factory.IndexStrategyFactory;
|
||||
import org.dromara.easyes.spring.property.EasyEsProperty;
|
||||
import org.dromara.easyes.common.property.EasyEsDynamicProperties;
|
||||
import org.dromara.easyes.common.property.EasyEsProperties;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
@ -57,6 +58,12 @@ public class MapperScannerConfigurer
|
||||
@Setter
|
||||
private RestHighLevelClientUtils restHighLevelClientUtils;
|
||||
|
||||
@Setter
|
||||
private EasyEsProperties easyEsProperties = new EasyEsProperties();
|
||||
|
||||
@Setter
|
||||
private EasyEsDynamicProperties easyEsDynamicProperties = new EasyEsDynamicProperties();
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private String beanName;
|
||||
@ -93,19 +100,19 @@ public class MapperScannerConfigurer
|
||||
scanner.registerFilters();
|
||||
// 索引策略工厂 -- 需要spring 注册bean xml/component 注解方式均可
|
||||
scanner.setIndexStrategyFactory(this.indexStrategyFactory);
|
||||
EasyEsProperty easyEsProperty = new EasyEsProperty(this.getEnvironment());
|
||||
scanner.setGlobalConfig(easyEsProperty.getGlobalConfig());
|
||||
scanner.setGlobalConfig(easyEsProperties.getGlobalConfig());
|
||||
// easy-es的连接对象注册 需要spring 注册bean xml/component 注解方式均可
|
||||
if (this.restHighLevelClientUtils == null) {
|
||||
RestHighLevelClientUtils restHighLevelClientUtils = new RestHighLevelClientUtils();
|
||||
Map<String, EasyEsProperty> datasourceMap = easyEsProperty.getDatasource();
|
||||
Map<String, EasyEsProperties> datasourceMap = this.easyEsDynamicProperties.getDatasource();
|
||||
if (CollectionUtils.isEmpty(datasourceMap)) {
|
||||
// 设置默认数据源,兼容不使用多数据源配置场景的老用户使用习惯
|
||||
datasourceMap.put(RestHighLevelClientUtils.DEFAULT_DS, easyEsProperty);
|
||||
datasourceMap.put(RestHighLevelClientUtils.DEFAULT_DS, easyEsProperties);
|
||||
}
|
||||
for (String key : datasourceMap.keySet()) {
|
||||
EasyEsProperty easyEsConfigProperties = datasourceMap.get(key);
|
||||
RestHighLevelClientUtils.registerRestHighLevelClient(key, restHighLevelClient(easyEsConfigProperties));
|
||||
EasyEsProperties easyEsConfigProperties = datasourceMap.get(key);
|
||||
RestHighLevelClientUtils.registerRestHighLevelClient(key, RestHighLevelClientUtils
|
||||
.restHighLevelClient(easyEsConfigProperties));
|
||||
}
|
||||
this.restHighLevelClientUtils = restHighLevelClientUtils;
|
||||
}
|
||||
@ -233,83 +240,4 @@ public class MapperScannerConfigurer
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getDatasource() {
|
||||
String dynamic = this.applicationContext.getEnvironment().getRequiredProperty("easy-es.dynamic");
|
||||
Properties properties = new Properties();
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
try {
|
||||
properties.load(new java.io.StringReader(dynamic));
|
||||
properties.forEach((key, value) -> map.put(key.toString(), value.toString()));
|
||||
} catch (Exception e) {
|
||||
// Handle exception
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static RestHighLevelClient restHighLevelClient(EasyEsProperty easyEsConfigProperties) {
|
||||
// 处理地址
|
||||
String address = easyEsConfigProperties.getAddress();
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
throw ExceptionUtils.eee("please config the es address");
|
||||
}
|
||||
if (!address.contains(COLON)) {
|
||||
throw ExceptionUtils.eee("the address must contains port and separate by ':'");
|
||||
}
|
||||
String schema = StringUtils.isEmpty(easyEsConfigProperties.getSchema())
|
||||
? DEFAULT_SCHEMA : easyEsConfigProperties.getSchema();
|
||||
List<HttpHost> hostList = new ArrayList<>();
|
||||
Arrays.stream(easyEsConfigProperties.getAddress().split(COMMA))
|
||||
.forEach(item -> hostList.add(new HttpHost(item.split(COLON)[0],
|
||||
Integer.parseInt(item.split(COLON)[1]), schema)));
|
||||
|
||||
// 转换成 HttpHost 数组
|
||||
HttpHost[] httpHost = hostList.toArray(new HttpHost[]{});
|
||||
|
||||
// 构建连接对象
|
||||
RestClientBuilder builder = RestClient.builder(httpHost);
|
||||
builder.setHttpClientConfigCallback(httpClientBuilder -> {
|
||||
// 设置心跳时间,最大连接数,最大连接路由
|
||||
Optional.ofNullable(easyEsConfigProperties.getKeepAliveMillis()).ifPresent(p -> httpClientBuilder.setKeepAliveStrategy((response, context) -> p));
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnTotal()).ifPresent(httpClientBuilder::setMaxConnTotal);
|
||||
Optional.ofNullable(easyEsConfigProperties.getMaxConnPerRoute()).ifPresent(httpClientBuilder::setMaxConnPerRoute);
|
||||
|
||||
// 设置账号密码
|
||||
String username = easyEsConfigProperties.getUsername();
|
||||
String password = easyEsConfigProperties.getPassword();
|
||||
if (StringUtils.isNotEmpty(username) && StringUtils.isNotEmpty(password)) {
|
||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||
new UsernamePasswordCredentials(username, password));
|
||||
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
|
||||
}
|
||||
|
||||
// https ssl ignore
|
||||
if (SchemaEnum.https.name().equals(schema)) {
|
||||
try {
|
||||
// 信任所有
|
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build();
|
||||
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||
httpClientBuilder.disableAuthCaching();
|
||||
httpClientBuilder.setSSLStrategy(sessionStrategy);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("restHighLevelClient build SSLContext exception: %s", e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw ExceptionUtils.eee(e);
|
||||
}
|
||||
}
|
||||
return httpClientBuilder;
|
||||
});
|
||||
|
||||
// 设置超时时间之类的
|
||||
builder.setRequestConfigCallback(requestConfigBuilder -> {
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectTimeout()).ifPresent(requestConfigBuilder::setConnectTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getSocketTimeout()).ifPresent(requestConfigBuilder::setSocketTimeout);
|
||||
Optional.ofNullable(easyEsConfigProperties.getConnectionRequestTimeout())
|
||||
.ifPresent(requestConfigBuilder::setConnectionRequestTimeout);
|
||||
return requestConfigBuilder;
|
||||
});
|
||||
return new RestHighLevelClient(builder);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
34
easy-es-spring/src/test/resources/application.properties
Normal file
34
easy-es-spring/src/test/resources/application.properties
Normal file
@ -0,0 +1,34 @@
|
||||
easy-es.keep-alive-millis=18000
|
||||
easy-es.address=198.163.192.11:9200
|
||||
easy-es.global-config.IKunMode=true
|
||||
easy-es.global-config.process-index-mode=manual
|
||||
easy-es.global-config.async-process-index-blocking=true
|
||||
easy-es.global-config.print-dsl=true
|
||||
easy-es.global-config.db-config.map-underscore-to-camel-case=true
|
||||
easy-es.global-config.db-config.id-type=customize
|
||||
easy-es.global-config.db-config.field-strategy=not_empty
|
||||
easy-es.global-config.db-config.refresh-policy=immediate
|
||||
easy-es.global-config.db-config.enable-track-total-hits=true
|
||||
|
||||
easy-es.dynamic.node1.keep-alive-millis=18000
|
||||
easy-es.dynamic.node1.address=198.163.192.11:9200
|
||||
easy-es.dynamic.node1.global-config.i-kun-mode=true
|
||||
easy-es.dynamic.node1.global-config.process-index-mode=manual
|
||||
easy-es.dynamic.node1.global-config.async-process-index-blocking=true
|
||||
easy-es.dynamic.node1.global-config.print-dsl=false
|
||||
easy-es.dynamic.node1.global-config.db-config.map-underscore-to-camel-case=true
|
||||
easy-es.dynamic.node1.global-config.db-config.id-type=customize
|
||||
easy-es.dynamic.node1.global-config.db-config.field-strategy=not_empty
|
||||
easy-es.dynamic.node1.global-config.db-config.refresh-policy=immediate
|
||||
easy-es.dynamic.node1.global-config.db-config.enable-track-total-hits=true
|
||||
easy-es.dynamic.node2.keep-alive-millis=18000
|
||||
easy-es.dynamic.node2.address=198.163.192.12:9200
|
||||
easy-es.dynamic.node2.global-config.i-kun-mode=true
|
||||
easy-es.dynamic.node2.global-config.process-index-mode=manual
|
||||
easy-es.dynamic.node2.global-config.async-process-index-blocking=true
|
||||
easy-es.dynamic.node2.global-config.print-dsl=true
|
||||
easy-es.dynamic.node2.global-config.db-config.map-underscore-to-camel-case=true
|
||||
easy-es.dynamic.node2.global-config.db-config.id-type=customize
|
||||
easy-es.dynamic.node2.global-config.db-config.field-strategy=not_empty
|
||||
easy-es.dynamic.node2.global-config.db-config.refresh-policy=immediate
|
||||
easy-es.dynamic.node2.global-config.db-config.enable-track-total-hits=true
|
||||
@ -1,10 +0,0 @@
|
||||
easy-es.keep-alive-millis=18000
|
||||
easy-es.global-config.i-kun-mode=true
|
||||
easy-es.global-config.process-index-mode=manual
|
||||
easy-es.global-config.async-process-index-blocking=true
|
||||
easy-es.global-config.print-dsl=true
|
||||
easy-es.global-config.db-config.map-underscore-to-camel-case=true
|
||||
easy-es.global-config.db-config.id-type=customize
|
||||
easy-es.global-config.db-config.field-strategy=not_empty
|
||||
easy-es.global-config.db-config.refresh-policy=immediate
|
||||
easy-es.global-config.db-config.enable-track-total-hits=true
|
||||
@ -1,21 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:property-placeholder location="classpath:easy-es.properties" />
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="indexStrategyFactory" class="org.dromara.easyes.spring.factory.IndexStrategyFactory"/>
|
||||
|
||||
<bean id="autoProcessIndexSmoothlyService" class="org.dromara.easyes.spring.index.AutoProcessIndexSmoothlyServiceImpl"/>
|
||||
|
||||
<bean id="autoProcessIndexNotSmoothlyService" class="org.dromara.easyes.spring.index.AutoProcessIndexNotSmoothlyServiceImpl"/>
|
||||
|
||||
<bean id="easyEsProperties" class="org.dromara.easyes.common.property.EasyEsProperties">
|
||||
<property name="address" value="192.168.1.123:9200"/>
|
||||
</bean>
|
||||
|
||||
<!-- easy-es配置 -->
|
||||
<bean id="mapperScannerConfigurer" class="org.dromara.easyes.spring.MapperScannerConfigurer">
|
||||
<property name="basePackage" value="org.dromara.easyes.test.mapper"/>
|
||||
<property name="indexStrategyFactory" ref="indexStrategyFactory"/>
|
||||
<property name="easyEsProperties" ref="easyEsProperties"/>
|
||||
</bean>
|
||||
</beans>
|
||||
Loading…
x
Reference in New Issue
Block a user