All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.zodiac.sentinel.base.datasource.SentinelDataSourceHandler Maven / Gradle / Ivy
package org.zodiac.sentinel.base.datasource;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.Environment;
import org.zodiac.commons.logging.SmartSlf4jLoggerFactory;
import org.zodiac.commons.util.Reflections;
import org.zodiac.commons.util.lang.Strings;
import org.zodiac.sentinel.base.config.SentinelConfigInfo;
import org.zodiac.sentinel.base.constants.SentinelDataSourceConstants;
import org.zodiac.sentinel.base.datasource.model.AbstractDataSourceInfo;
import org.zodiac.sentinel.base.support.SentinelDataSourcesContext;
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
public class SentinelDataSourceHandler implements SmartInitializingSingleton {
private static final Logger LOG = SmartSlf4jLoggerFactory.getLogger(SentinelDataSourceHandler.class);
private List dataTypeList = Arrays.asList("json", "xml");
private final String DATA_TYPE_FIELD = "dataType";
private final String CUSTOM_DATA_TYPE = "custom";
private final String CONVERTER_CLASS_FIELD = "converterClass";
private final DefaultListableBeanFactory beanFactory;
private final SentinelConfigInfo sentinelConfigInfo;
private final Environment env;
public SentinelDataSourceHandler(DefaultListableBeanFactory beanFactory, SentinelConfigInfo sentinelConfigInfo,
Environment env) {
this.beanFactory = beanFactory;
this.sentinelConfigInfo = sentinelConfigInfo;
this.env = env;
}
@Override
public void afterSingletonsInstantiated() {
sentinelConfigInfo.getDatasource().forEach((dataSourceConfigName, dataSourceConfigInfo) -> {
try {
List validFields = dataSourceConfigInfo.getValidField();
if (validFields.size() != 1) {
LOG.error("[Sentinel Starter] DataSource {} multi datasource active and won't loaded: {} .",
dataSourceConfigName, dataSourceConfigInfo.getValidField());
return;
}
AbstractDataSourceInfo abstractSentinelDataSourceInfo = dataSourceConfigInfo.getValidDataSourceInfo();
/*abstractSentinelDataSourceInfo 为 'SentinelConfigInfo.datasource'的Map中 的value,即 AbstractSentinelDataSourceInfo的各个实现类。*/
abstractSentinelDataSourceInfo.setEnvironment(env);
abstractSentinelDataSourceInfo.preCheck(dataSourceConfigName);
/*格式为 “{SentinelConfigInfo.datasource的Map key}-sentinel-{file|apollo|nacos|redis}-datasource” 。*/
String dataSourceBeanName = String.format(SentinelDataSourceConstants.DATASOURCE_BEAN_NAME_TEMPLATE,
dataSourceConfigName, validFields.get(0));
registerBean(dataSourceConfigName, abstractSentinelDataSourceInfo, dataSourceBeanName);
} catch (Exception e) {
LOG.error(String.format("[Sentinel Starter] DataSource %s build error: %s", dataSourceConfigName, e.getMessage()), e);
}
});
}
private void registerBean(final String dataSourceConfigName, final AbstractDataSourceInfo dataSourceInfo, String dataSourceName) {
Map propertyMap =
Arrays.stream(dataSourceInfo.getClass().getDeclaredFields()).collect(HashMap::new, (m, v) -> {
try {
v.setAccessible(true);
m.put(v.getName(), v.get(dataSourceInfo));
} catch (IllegalAccessException e) {
String error = String.format("[Sentinel Starter] DataSource %s field: %s invoke error", dataSourceName, v.getName());
LOG.error(error);
throw new RuntimeException(error, e);
}
}, HashMap::putAll);
propertyMap.put(CONVERTER_CLASS_FIELD, dataSourceInfo.getConverterClass());
propertyMap.put(DATA_TYPE_FIELD, dataSourceInfo.getDataType());
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(dataSourceInfo.getFactoryBeanName());
propertyMap.forEach((propertyName, propertyValue) -> {
Field field = Reflections.findField(dataSourceInfo.getClass(), propertyName);
if (null == field) {
return;
}
if (DATA_TYPE_FIELD.equals(propertyName)) {
String dataType = Strings.trimAllWhitespace(propertyValue.toString());
if (CUSTOM_DATA_TYPE.equals(dataType)) {
try {
if (Strings.isEmpty(dataSourceInfo.getConverterClass())) {
throw new RuntimeException("[Sentinel Starter] DataSource " + dataSourceName
+ "dataType is custom, please set converter-class " + "property");
}
/*Construct custom Converter with 'converterClass' configuration and register.*/
String customConvertBeanName = "sentinel-" + dataSourceInfo.getConverterClass();
if (!this.beanFactory.containsBean(customConvertBeanName)) {
this.beanFactory.registerBeanDefinition(customConvertBeanName,
BeanDefinitionBuilder
.genericBeanDefinition(Class.forName(dataSourceInfo.getConverterClass()))
.getBeanDefinition());
}
builder.addPropertyReference("converter", customConvertBeanName);
} catch (ClassNotFoundException e) {
LOG.error("[Sentinel Starter] DataSource " + dataSourceName + " handle "
+ dataSourceInfo.getClass().getSimpleName() + " error, class name: "
+ dataSourceInfo.getConverterClass());
throw new RuntimeException("[Sentinel Starter] DataSource " + dataSourceName + " handle "
+ dataSourceInfo.getClass().getSimpleName() + " error, class name: "
+ dataSourceInfo.getConverterClass(), e);
}
} else {
if (!dataTypeList.contains(Strings.trimAllWhitespace(propertyValue.toString()))) {
throw new RuntimeException(
"[Sentinel Starter] DataSource " + dataSourceName + " dataType: " + propertyValue
+ " is not support now. please using these types: " + dataTypeList.toString());
}
/*Converter type now support xml or json.*/
/*The bean name of these converters wrapped by 'sentinel-{converterType}-{ruleType}-converter'*/
builder.addPropertyReference("converter", "sentinel-" + propertyValue.toString() + "-"
+ dataSourceInfo.getRule().getName() + "-converter");
}
} else if (CONVERTER_CLASS_FIELD.equals(propertyName)) {
return;
} else {
/*Wired properties.*/
Optional.ofNullable(propertyValue).ifPresent(v -> builder.addPropertyValue(propertyName, v));
}
});
this.beanFactory.registerBeanDefinition(dataSourceName, builder.getBeanDefinition());
/*Init in Spring.*/
AbstractDataSource newDataSource = (AbstractDataSource)this.beanFactory.getBean(dataSourceName);
/*Register property in RuleManager.*/
dataSourceInfo.postRegister(newDataSource);
/*Add dataSouece bean to Context.*/
SentinelDataSourcesContext.addDataSource(dataSourceConfigName, dataSourceInfo, dataSourceName, newDataSource);
}
}