You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
8.9 KiB

package com.bsmlab.dfx.agent.config;
import com.bsmlab.dfx.agent.config.datasource.DynamicDataSourceService;
import com.bsmlab.dfx.agent.config.datasource.DynamicRoutingDataSource;
import com.bsmlab.dfx.agent.config.datasource.RefreshableSqlSessionFactoryBean;
import io.micrometer.common.util.StringUtils;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executor;
@Slf4j
@Getter
@Configuration
@RequiredArgsConstructor
@MapperScans({
@MapperScan("com.bsmlab.dfx.agent")
})
public class DfxAgentConfiguration {
// gradle bootRun 실행 설정
// bootRun --args=" --setting.file=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples\dfxagent.json"
// command line java 실행 설정
// java -jar dfxagent.jar --setting.file=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples\dfxagent.json
//example: setting.file=D:\projects\bsm-lab\dfx\dfxagent\src\docs\settings-examples\dfxagent.json
@Value("${setting.file}")
private String settingFile;
private Map<String, SqlSessionFactory> temporarySqlSessionFactoryMap = new HashMap<>();
Map<String, DataSourceTransactionManager> temporaryTransactionManagerMap = new HashMap<>();
// agent 설정 관리자. 대부분의 기능에 필요함
@Bean(name = "agentConfigReader")
public AgentConfigReader agentConfigReader() { // 실행확인됨
if(StringUtils.isBlank(this.settingFile)) {
log.error("cannot found a setting file. {}", this.settingFile);
log.error("exit application");
System.exit(0);
}
AgentConfigReader agentConfigReader = new AgentConfigReader();
agentConfigReader.loadConfigFile(this.settingFile);
return agentConfigReader;
}
// 다중 데이터 소스 생성
@Bean(name = "dynamicRoutingDataSource")
public DynamicRoutingDataSource dynamicRoutingDataSource(AgentConfigReader agentConfigReader) throws IOException { // 실행확인됨
DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
Map<String, SqlSessionFactory> sqlSessionFactoryMap = new HashMap<>();
Map<String, DataSourceTransactionManager> transactionManagerMap = new HashMap<>();
List<String> xmlPathList = agentConfigReader.getAgentConfigDto().getSqlMapperLocations();
List<Resource> resourceList = new ArrayList<>();
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
for(String pathString : xmlPathList) {
Resource[] resourceArray = pathMatchingResourcePatternResolver.getResources("file:" + pathString);
resourceList.addAll(Arrays.asList(resourceArray));
}
List<AgentConfigDto.DataSourceConfig> dataSourceConfigList = agentConfigReader.getAgentConfigDto().getDataSourceConfig();
for(AgentConfigDto.DataSourceConfig dataSourceConfig : dataSourceConfigList) {
try {
BasicDataSource dataSource = createBasicDataSource(dataSourceConfig);
SqlSessionFactoryBean sqlSessionFactoryBean = new RefreshableSqlSessionFactoryBean();//new SqlSessionFactoryBean();
org.apache.ibatis.session.Configuration mybatisConfiguration = new org.apache.ibatis.session.Configuration();
sqlSessionFactoryBean.setConfiguration(mybatisConfiguration);
sqlSessionFactoryBean.setFailFast(true);
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(resourceList.toArray(new Resource[0]));
sqlSessionFactoryBean.afterPropertiesSet();
sqlSessionFactoryMap.put(dataSourceConfig.getDataSourceId(), sqlSessionFactoryBean.getObject());
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
transactionManagerMap.put(dataSourceConfig.getDataSourceId(), transactionManager);
dynamicRoutingDataSource.addDataSource(dataSourceConfig.getDataSourceId(), dataSource);
} catch (Exception e) {
log.error("DynamicRoutingDataSource 생성 중 오류: {}", e.getMessage(), e);
throw new RuntimeException(e);
}
}
this.temporarySqlSessionFactoryMap = sqlSessionFactoryMap;
this.temporaryTransactionManagerMap = transactionManagerMap;
return dynamicRoutingDataSource;
}
private static BasicDataSource createBasicDataSource(AgentConfigDto.DataSourceConfig dataSourceConfig) {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(dataSourceConfig.getDriverClassName());
dataSource.setUrl(dataSourceConfig.getUrl());
dataSource.setUsername(dataSourceConfig.getUsername());
dataSource.setPassword(dataSourceConfig.getPassword());
if(oracle.jdbc.driver.OracleDriver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1 FROM DUAL");
}
else if(org.postgresql.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(com.mysql.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(org.mariadb.jdbc.Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1");
}
else if(com.ibm.db2.jcc.DB2Driver.class.getCanonicalName().equals(dataSourceConfig.getDriverClassName())) {
dataSource.setValidationQuery("SELECT 1 FROM SYSIBM.SYSDUMMY1");
}
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTestOnCreate(true);
dataSource.setTestWhileIdle(true);
dataSource.setInitialSize(3);
dataSource.setMinIdle(3);
dataSource.setMaxIdle(30);
dataSource.setMaxTotal(30);
return dataSource;
}
// 다중 데이터 소스와 그에 해당하는 sqlSession, transactionManager 설정
@Bean(name = "dynamicDataSourceService")
public DynamicDataSourceService dynamicDataSourceService() { // 실행확인됨
DynamicDataSourceService dynamicDataSourceService = new DynamicDataSourceService();
dynamicDataSourceService.setSqlSessionFactoryMap(this.temporarySqlSessionFactoryMap);
dynamicDataSourceService.setTransactionManagerMap(this.temporaryTransactionManagerMap);
return dynamicDataSourceService;
}
// (수신 처리) 메시지 수신 - 저장 후 수신 메시지 처리 쓰레드 설정
@Bean(name = "dropBoxProcessorThreadPoolTaskExecutor")
public Executor dropBoxProcessorThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor dropBoxProcessorThreadPoolTaskExecutor = new ThreadPoolTaskExecutor();
dropBoxProcessorThreadPoolTaskExecutor.setCorePoolSize(30); // 최소 쓰레드
dropBoxProcessorThreadPoolTaskExecutor.setMaxPoolSize(300); // 최대 쓰레드
dropBoxProcessorThreadPoolTaskExecutor.setQueueCapacity(300); // 대기 큐
dropBoxProcessorThreadPoolTaskExecutor.setThreadNamePrefix("dropBoxProcessor-");
dropBoxProcessorThreadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true); // 종료 시 대기 여부
dropBoxProcessorThreadPoolTaskExecutor.initialize();
return dropBoxProcessorThreadPoolTaskExecutor;
}
// (송신 처리) 메시지 송신 쓰레드 설정
@Bean(name = "scheduledPostmanThreadPoolTaskScheduler")
public ThreadPoolTaskScheduler scheduledPostmanThreadPoolTaskScheduler() { // 실행확인됨
ThreadPoolTaskScheduler scheduledPostmanThreadPoolTaskScheduler = new ThreadPoolTaskScheduler();
scheduledPostmanThreadPoolTaskScheduler.setPoolSize(10);
scheduledPostmanThreadPoolTaskScheduler.setThreadNamePrefix("postman-scheduler-");
scheduledPostmanThreadPoolTaskScheduler.initialize();
return scheduledPostmanThreadPoolTaskScheduler;
}
}