Commit ccd54f84 authored by neo's avatar neo

[dev] delete AopSharding databases

parent a8cecf99
package pwc.taxtech.atms.common.datasource;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
@Aspect
public class AopShardingHolder {
private static Logger logger = LoggerFactory.getLogger(AopShardingHolder.class);
private static final String DATABASE_NAME_HEADER = "from";
private static final String DATABASE_NAME_SPLIT = "@";
@Autowired
HttpServletRequest request;
@Pointcut("execution(public * pwc.taxtech.atms.controller.*.*(..))")
public void pointCut() {
// 定义Pointcut 此方法不能有返回值,该方法只是一个标示
}
@Before("pointCut()")
public void before(JoinPoint joinPoint) {
try {
String header = request.getHeader(DATABASE_NAME_HEADER);
if (StringUtils.isNotBlank(header)) {
if (logger.isDebugEnabled()) {
logger.debug("aop set datasource:{}", header);
}
String[] arr = StringUtils.split(header, DATABASE_NAME_SPLIT);
String name = arr[0];
if (name.length() > 0 && !StringUtils.contains(name, DATABASE_NAME_SPLIT)) {
ShardingContextHolder.setDataSourceKey(name);
}
}
} catch (Exception e) {
logger.error("aop set database error.", e);
}
}
@After("pointCut()")
public void after(JoinPoint joinPoint) {
}
@AfterThrowing(pointcut = "pointCut()", throwing = "error")
public void afterThrowing(JoinPoint joinPoint, Throwable error) {
}
}
\ No newline at end of file
package pwc.taxtech.atms.common.datasource;
public class DataSourceConfig {
private String url;
private String username;
private String password;
private Integer clientTimeout;
private Integer threadNum;
private Integer transferFileType;
private boolean renameUploaded;
private Integer retryTimes;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getClientTimeout() {
return clientTimeout;
}
public void setClientTimeout(Integer clientTimeout) {
this.clientTimeout = clientTimeout;
}
public Integer getThreadNum() {
return threadNum;
}
public void setThreadNum(Integer threadNum) {
this.threadNum = threadNum;
}
public Integer getTransferFileType() {
return transferFileType;
}
public void setTransferFileType(Integer transferFileType) {
this.transferFileType = transferFileType;
}
public boolean isRenameUploaded() {
return renameUploaded;
}
public void setRenameUploaded(boolean renameUploaded) {
this.renameUploaded = renameUploaded;
}
public Integer getRetryTimes() {
return retryTimes;
}
public void setRetryTimes(Integer retryTimes) {
this.retryTimes = retryTimes;
}
}
package pwc.taxtech.atms.common.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.KeyedPooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pwc.taxtech.atms.exception.ParameterException;
public class DataSourceFactory implements KeyedPooledObjectFactory<String, DruidDataSource> {
private static final Logger logger = LoggerFactory.getLogger(DataSourceFactory.class);
private DataSourceConfig dataSourceConfig;
private static final String SYMBOL = "demo_db_name";
public DataSourceFactory(DataSourceConfig dataSourceConfig) {
this.dataSourceConfig = dataSourceConfig;
}
@Override
public PooledObject<DruidDataSource> makeObject(String s) throws Exception {
if (StringUtils.isBlank(s)) {
throw new ParameterException("empty database name.");
}
DruidDataSource dynamicDataSource = new DruidDataSource();
String url = StringUtils.replace(dataSourceConfig.getUrl(), SYMBOL, s);
dynamicDataSource.setUrl(url);
dynamicDataSource.setUsername(dataSourceConfig.getUsername());
dynamicDataSource.setPassword(dataSourceConfig.getPassword());
dynamicDataSource.init();
return new DefaultPooledObject<>(dynamicDataSource);
}
@Override
public void destroyObject(String s, PooledObject<DruidDataSource> pooledObject) throws Exception {
pooledObject.getObject().close();
}
@Override
public boolean validateObject(String s, PooledObject<DruidDataSource> pooledObject) {
try {
return pooledObject.getObject().isEnable();
} catch (Exception e) {
logger.error("Failed to validate DruidDataSource: ", e);
}
return false;
}
@Override
public void activateObject(String s, PooledObject<DruidDataSource> pooledObject) throws Exception {
}
@Override
public void passivateObject(String s, PooledObject<DruidDataSource> pooledObject) throws Exception {
}
}
package pwc.taxtech.atms.common.datasource;
public class ShardingContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
/**
* 设置数据库名
*
* @param key key
*/
public static void setDataSourceKey(String key) {
contextHolder.set(key);
}
/**
* 获取数据库名
*
* @return key
*/
public static String getDataSourceKey() {
return contextHolder.get();
}
}
......@@ -5,6 +5,6 @@ public class Exceptions {
public static final FormulaException BB_REPORT_NULL = new FormulaException("cell report is null");
public static final FormulaException BB_CELL_DATA_NULL = new FormulaException("cell data is null");
public static final FormulaException BB_CELL_DATA_EMPTY = new FormulaException("cell data is empty");
public static final FormulaException BB_EMPTY = new FormulaException("db name is empty");
public static final FormulaException PROJECT_EMPTY = new FormulaException("project is empty");
public static final FormulaException BAD_BBVO_PARAMS = new FormulaException("bad params for bb fromular express data");
}
package pwc.taxtech.atms.service;
import pwc.taxtech.atms.dto.OperationResultDto;
import java.util.List;
public interface ICitTBDataImportService {
OperationResultDto<Boolean> clearTableByPeriods(List<Integer> periods);
}
package pwc.taxtech.atms.service.impl;
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Service;
import pwc.taxtech.atms.common.datasource.DataSourceConfig;
import pwc.taxtech.atms.common.datasource.DataSourceFactory;
import pwc.taxtech.atms.common.datasource.ShardingContextHolder;
import pwc.taxtech.atms.exception.ParameterException;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
@Service("DynamicDataSource")
public class DataSourcePoolService extends AbstractRoutingDataSource {
private GenericKeyedObjectPool<String, DruidDataSource> dataSourcePool;
@Value("${jdbc_url_demo}")
private String demoUrl;
@Value("${jdbc_user}")
private String jdbcUser;
@Value("${jdbc_password}")
private String jdbcPwd;
@PostConstruct
public void init() throws Exception {
DataSourceConfig config = new DataSourceConfig();
config.setUrl(demoUrl);
config.setUsername(jdbcUser);
config.setPassword(jdbcPwd);
GenericKeyedObjectPoolConfig poolConfig = new GenericKeyedObjectPoolConfig();
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setMaxTotalPerKey(1);
poolConfig.setMaxIdlePerKey(1);
dataSourcePool = new GenericKeyedObjectPool<>(new DataSourceFactory(config), poolConfig);
this.setTargetDataSources(Maps.newHashMap());
}
@Override
protected Object determineCurrentLookupKey() {
return ShardingContextHolder.getDataSourceKey();
}
@Override
protected synchronized DataSource determineTargetDataSource() {
try {
String key = ShardingContextHolder.getDataSourceKey();
DruidDataSource dataSource = dataSourcePool.borrowObject(key);
dataSourcePool.returnObject(key, dataSource);
return dataSource;
} catch (Exception e) {
throw new RuntimeException("determineTargetDataSource error.", e);
}
}
private void createDataSource(String key) {
if (StringUtils.isBlank(key)) {
throw new ParameterException("DataSource name is empty.");
}
try {
dataSourcePool.addObject(key);
} catch (Exception e) {
throw new RuntimeException("createDataSource error.", e);
}
}
@Bean
public SqlSessionFactory dynamicSqlSessionFactory(
@Qualifier("DynamicDataSource") DataSource dynamicDataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dynamicDataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:pwc/taxtech/atms/vat/dao/**/*Mapper.xml"));
return bean.getObject();
}
@Bean
public SqlSessionTemplate dynamicSqlSessionTemplate(
@Qualifier("dynamicSqlSessionFactory") SqlSessionFactory sqlSessionFactory)
throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public JdbcTemplate dynamicJdbcTemplate(@Qualifier("DynamicDataSource")DataSource dynamicDataSource) {
return new JdbcTemplate(dynamicDataSource);
}
}
package pwc.taxtech.atms.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pwc.taxtech.atms.constant.VatErpImportValidation;
import pwc.taxtech.atms.dao.CitTBDataImportMapper;
import pwc.taxtech.atms.dto.OperationResultDto;
import pwc.taxtech.atms.service.ICitTBDataImportService;
import java.util.List;
@Service
public class ICitTBDataImportServiceImpl implements ICitTBDataImportService {
private static Logger LOGGER = LoggerFactory.getLogger(ICitTBDataImportServiceImpl.class);
@Autowired
CitTBDataImportMapper citTBDataImportMapper;
@Override
public OperationResultDto<Boolean> clearTableByPeriods(List<Integer> periods) {
return clearTableByPeriods(periods, true);
}
public OperationResultDto<Boolean> clearTableByPeriods(List<Integer> periods, Boolean isClearTb) {
try {
periods.forEach(period -> {
clearCustTable(period, VatErpImportValidation.CompanyBalanceTbName);
if (isClearTb) {
clearCustTable(period, VatErpImportValidation.CustBalanceTb);
}
clearCustTable(period, VatErpImportValidation.BalanceTb);
clearVoucherTable(period);
clearRemapTable(period);
});
return OperationResultDto.SUCCESS_EMPTY;
}catch (Exception e){
LOGGER.error("ClearTableByPeriods method error",e);
return OperationResultDto.errorFor(e.getMessage());
}
}
private void clearRemapTable(Integer period) {
citTBDataImportMapper.deleteByNameAndPeriod(VatErpImportValidation.AccountRemapTb, isImportByPeriod(period) ? period : null);
}
private void clearVoucherTable(Integer period) {
citTBDataImportMapper.deleteByNameAndPeriod(VatErpImportValidation.VoucherTbName, isImportByPeriod(period) ? period : null);
}
//清除试算平衡相关的Table
private void clearCustTable(Integer period, String tbName) {
if (isImportByPeriod(period) && !tbName.equals(VatErpImportValidation.BalanceTb))
if (tbName.equals(VatErpImportValidation.CompanyBalanceTbName) || tbName.equals(VatErpImportValidation.CustBalanceTb)) {
citTBDataImportMapper.deleteByPeriod(period, tbName);
if(tbName.equals(VatErpImportValidation.CustBalanceTb)){
citTBDataImportMapper.deleteByGreaterPeriod(period, tbName);
}
}
else citTBDataImportMapper.deleteByNameAndPeriod(tbName, null);
}
private Boolean isImportByPeriod(int period) {
return period >= 0;
}
}
......@@ -72,8 +72,8 @@ public class FormulaAgent extends VatAbstractService {
return null;
}
public String getPastProjectDbName(int year, String orgId) {
return adminMp.getPastProjectDbName(year, orgId);
public String getPastProjectId(int year, String orgId) {
return adminMp.getPastProjectId(year, orgId);
}
public CellData getCellData(String templateId, String cellId, int periodId) {
......
......@@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import pwc.taxtech.atms.common.CommonUtils;
import pwc.taxtech.atms.common.datasource.ShardingContextHolder;
import pwc.taxtech.atms.common.util.SpringContextUtil;
import pwc.taxtech.atms.constant.enums.CellDataSourceType;
import pwc.taxtech.atms.constant.enums.EnumOperationType;
......@@ -24,8 +23,6 @@ import pwc.taxtech.atms.dto.vatdto.ReportCellDataSourceDto;
import pwc.taxtech.atms.dto.vatdto.ReportDataDto;
import pwc.taxtech.atms.dto.vatdto.VatEnterpriseAccountResultDto;
import pwc.taxtech.atms.entity.*;
import pwc.taxtech.atms.entity.EnterpriseAccount;
import pwc.taxtech.atms.entity.EnterpriseAccountExample;
import pwc.taxtech.atms.exception.NotSupportedException;
import pwc.taxtech.atms.service.impl.CellConfigTranslater;
import pwc.taxtech.atms.vat.dpo.DataSourceCellDataDto;
......@@ -97,9 +94,7 @@ public class ReportServiceImpl extends VatAbstractService implements ReportServi
}
}
String dbName = ShardingContextHolder.getDataSourceKey();
Map<String, Object> map = new HashMap<>();
map.put("dbName", dbName);
map.put("period", period);
map.put("projectId", projectId);
map.put("templateGroupId", templateGroupId);
......
......@@ -9,7 +9,6 @@ import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pwc.taxtech.atms.common.datasource.ShardingContextHolder;
import pwc.taxtech.atms.common.util.MyAsserts;
import pwc.taxtech.atms.constant.enums.FormulaDataSourceDetailType;
import pwc.taxtech.atms.dpo.CellTemplatePerGroupDto;
......@@ -110,26 +109,12 @@ public class BB extends FunctionBase implements FreeRefFunction {
// bo.disCount();
CellData cellData = null;
String dbName = agent.getPastProjectDbName(curPeriod.getCurYear(),
String projectId = agent.getPastProjectId(curPeriod.getCurYear(),
formulaContext.getOrganizationId());
MyAsserts.assertNotEmpty(dbName, Exceptions.BB_EMPTY);
String currentProjectDb = ShardingContextHolder.getDataSourceKey();
if (currentProjectDb.equals(dbName)) {
cellData = agent.getCellData(cellTemplateData.getReportTemplateId(),
cellTemplateData.getCellTemplateId(), curPeriod.getCurPeriod());
} else {
try {
ShardingContextHolder.setDataSourceKey(dbName);
cellData = agent.getCellData(cellTemplateData.getReportTemplateId(),
cellTemplateData.getCellTemplateId(), curPeriod.getCurPeriod());
} catch (Exception e) {
LOGGER.warn("get data exception with dbName{} currentDb {}", dbName, currentProjectDb, e);
throw e;
} finally {
ShardingContextHolder.setDataSourceKey(currentProjectDb);
}
}
MyAsserts.assertNotEmpty(projectId, Exceptions.PROJECT_EMPTY);
cellData = agent.getCellData(cellTemplateData.getReportTemplateId(),
cellTemplateData.getCellTemplateId(), curPeriod.getCurPeriod());
nullCellDto.extractFromGroup(bo, curPeriod, cellData, cellTemplateData);
// todo: fix datasource name by templateList(neo)
......
package pwc.taxtech.atms;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import pwc.taxtech.atms.common.datasource.ShardingContextHolder;
import pwc.taxtech.atms.vat.dao.ReportMapper;
import pwc.taxtech.atms.vat.entity.Report;
import pwc.taxtech.atms.vat.entity.ReportExample;
import java.util.List;
public class DataSourceSwitch extends CommonIT {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private ReportMapper reportMapper;
@Test
public void insertChieseCharacter() {
ShardingContextHolder.setDataSourceKey("a1700000");
ReportExample example = new ReportExample();
example.createCriteria().andTemplateIdEqualTo(Long.valueOf("9951852766564352"))
.andPeriodEqualTo(1);
List<Report> reports = reportMapper.selectByExample(example);
System.out.println(reports.size());
ShardingContextHolder.setDataSourceKey("a1800013");
System.out.println(reportMapper.selectByExample(example).size());
ShardingContextHolder.setDataSourceKey("a1700000");
System.out.println(reportMapper.selectByExample(example).size());
}
}
......@@ -55,5 +55,5 @@ public interface FormulaAdminMapper extends MyMapper {
" AND p.Is_Active = 1 " +
" AND ROWNUM=1"+
"ORDER BY ps.Service_Type_ID ")
String getPastProjectDbName(@Param("year") int year, @Param("orgId") String organizationId);
String getPastProjectId(@Param("year") int year, @Param("orgId") String organizationId);
}
......@@ -137,10 +137,10 @@
B.PERIOD,
B.TEMPLATE_ID
FROM
${DB_NAME}.REPORT b
REPORT b
WHERE
b.PERIOD = #{period,jdbcType=INTEGER}
AND B.PROJECT_ID = #{projectID,jdbcType=VARCHAR}
AND B.PROJECT_ID = #{projectId,jdbcType=VARCHAR}
)
D
ON
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment