fix: NEZ-2203 从 /opt/nezha/nz-web/config/nezha.properties 获取数据源信息
1. 升级之后对 nezha.properties database.pin 加密
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
package net.geedge;
|
package net.geedge;
|
||||||
|
|
||||||
|
import cn.hutool.setting.dialect.Props;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class TransferApplication {
|
public class TransferApplication {
|
||||||
@@ -13,4 +14,11 @@ public class TransferApplication {
|
|||||||
SpringApplication.run(TransferApplication.class, args);
|
SpringApplication.run(TransferApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Properties nezhaProperties() {
|
||||||
|
//Properties properties = new Props("D:\\workspeace\\nz-transfer\\src\\main\\resources\\nezha.properties", "UTF-8");
|
||||||
|
Properties properties = new Props("/opt/nezha/nz-web/config/nezha.properties", "UTF-8");
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
118
src/main/java/net/geedge/config/DataSourceConfig.java
Normal file
118
src/main/java/net/geedge/config/DataSourceConfig.java
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package net.geedge.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.log.Log;
|
||||||
|
import com.alibaba.druid.pool.DruidDataSource;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class DataSourceConfig {
|
||||||
|
|
||||||
|
private static final Log log = Log.get();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("nezhaProperties")
|
||||||
|
private Map<String, String> nezhaProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据源配置项
|
||||||
|
*/
|
||||||
|
@Value("${spring.datasource.druid.driver-class-name:com.mysql.jdbc.Driver}")
|
||||||
|
private String driver;
|
||||||
|
@Value("${spring.datasource.druid.url-pattern:jdbc:mysql://{{host}}:{{port}}/{{dbName}}?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false}")
|
||||||
|
private String urlPattern;
|
||||||
|
@Value("${spring.datasource.druid.initial-size:10}")
|
||||||
|
private int initialSize;
|
||||||
|
@Value("${spring.datasource.druid.max-active:100}")
|
||||||
|
private int dbMaxActive;
|
||||||
|
@Value("${spring.datasource.druid.min-idle:5}")
|
||||||
|
private int dbMinIdle;
|
||||||
|
@Value("${spring.datasource.druid.max-wait:60000}")
|
||||||
|
private int dbMaxWait;
|
||||||
|
@Value("${spring.datasource.druid.pool-prepared-statements:true}")
|
||||||
|
private boolean poolPreparedStatements;
|
||||||
|
@Value("${spring.datasource.druid.validation-query:SELECT 1}")
|
||||||
|
private String validationQuery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建自定义数据源
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
if (!StrUtil.isAllNotBlank(nezhaProperties.get("database.host"), nezhaProperties.get("database.user"), nezhaProperties.get("database.name"))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.info("datasource config,user:{}, url: {}", nezhaProperties.get("database.user"), this.getDbUrl());
|
||||||
|
DruidDataSource dataSource = new DruidDataSource();
|
||||||
|
dataSource.setUrl(this.getDbUrl());
|
||||||
|
dataSource.setUsername(nezhaProperties.get("database.user"));
|
||||||
|
dataSource.setPassword(nezhaProperties.get("database.pin"));
|
||||||
|
dataSource.setDriverClassName(this.driver);
|
||||||
|
dataSource.setInitialSize(this.initialSize);
|
||||||
|
dataSource.setMaxActive(this.dbMaxActive);
|
||||||
|
dataSource.setMinIdle(this.dbMinIdle);
|
||||||
|
dataSource.setMaxWait(this.dbMaxWait);
|
||||||
|
dataSource.setPoolPreparedStatements(this.poolPreparedStatements);
|
||||||
|
dataSource.setValidationQuery(this.validationQuery);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回 data 数据库的事务
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
static class DataSourceTransactionManagerConfiguration {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
private final TransactionManagerCustomizers transactionManagerCustomizers;
|
||||||
|
|
||||||
|
DataSourceTransactionManagerConfiguration(DataSource dataSource,
|
||||||
|
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
this.transactionManagerCustomizers = transactionManagerCustomizers
|
||||||
|
.getIfAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TransactionDefinition transactionDefinition() {
|
||||||
|
return new DefaultTransactionDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSourceTransactionManager transactionManager() {
|
||||||
|
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
|
||||||
|
this.dataSource);
|
||||||
|
if (this.transactionManagerCustomizers != null) {
|
||||||
|
this.transactionManagerCustomizers.customize(transactionManager);
|
||||||
|
}
|
||||||
|
return transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据库连接url
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getDbUrl() {
|
||||||
|
return this.urlPattern.replace("{{host}}", nezhaProperties.get("database.host"))
|
||||||
|
.replace("{{port}}", StrUtil.emptyToDefault(nezhaProperties.get("database.port"), "3306"))
|
||||||
|
.replace("{{dbName}}", nezhaProperties.get("database.name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
package net.geedge.handler;
|
package net.geedge.handler;
|
||||||
|
|
||||||
import cn.hutool.log.Log;
|
import cn.hutool.log.Log;
|
||||||
|
import cn.hutool.setting.dialect.Props;
|
||||||
import net.geedge.dao.SqlDao;
|
import net.geedge.dao.SqlDao;
|
||||||
|
import net.geedge.util.AesUtil;
|
||||||
|
import net.geedge.util.Constant;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
@@ -10,7 +13,9 @@ import org.springframework.stereotype.Component;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 此类用于数据同步完成后 清除无用表
|
* 此类用于数据同步完成后
|
||||||
|
* 1. 清除无用表
|
||||||
|
* 2. 修改 nezha.properties 密码加密
|
||||||
* @author admin
|
* @author admin
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -41,6 +46,20 @@ public class AfterHandler implements CommandLineRunner {
|
|||||||
}
|
}
|
||||||
sqlDao.execute(sb.toString());
|
sqlDao.execute(sb.toString());
|
||||||
log.info("remove table successful");
|
log.info("remove table successful");
|
||||||
|
|
||||||
|
// nezha.properties database.pin
|
||||||
|
// 21.07 -> 22.02 pin 加密
|
||||||
|
String propsPath = "/opt/nezha/nz-web/config/nezha.properties";
|
||||||
|
Props props = new Props(propsPath, "UTF-8");
|
||||||
|
|
||||||
|
String dbPin = props.getStr("database.pin");
|
||||||
|
String encryptPin = AesUtil.encrypt(dbPin, Constant.AES_SECRET_KEY);
|
||||||
|
props.put("database.pin", encryptPin);
|
||||||
|
|
||||||
|
// store
|
||||||
|
props.store(propsPath);
|
||||||
|
log.info("nezha.properties database.pin encrypt successful");
|
||||||
|
|
||||||
log.info("-----------------transfer data success-----------------------");
|
log.info("-----------------transfer data success-----------------------");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
70
src/main/java/net/geedge/util/AesUtil.java
Normal file
70
src/main/java/net/geedge/util/AesUtil.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package net.geedge.util;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get from the nz web
|
||||||
|
*/
|
||||||
|
public class AesUtil {
|
||||||
|
|
||||||
|
private static final String KEY_ALGORITHM = "AES";
|
||||||
|
// 默认的加密算法
|
||||||
|
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
|
||||||
|
|
||||||
|
public static String encrypt(String content, byte[] key) {
|
||||||
|
try {
|
||||||
|
// 创建密码器
|
||||||
|
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
||||||
|
byte[] byteContent = content.getBytes("utf-8");
|
||||||
|
|
||||||
|
// 初始化为加密模式的密码器
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
|
||||||
|
byte[] result = cipher.doFinal(byteContent);// 加密
|
||||||
|
return cn.hutool.core.util.HexUtil.encodeHexStr(result);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decrypt(String content, byte[] key) {
|
||||||
|
try {
|
||||||
|
// 实例化
|
||||||
|
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
||||||
|
|
||||||
|
// 使用密钥初始化,设置为解密模式
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
|
||||||
|
// 执行操作
|
||||||
|
byte[] result = cipher.doFinal(cn.hutool.core.util.HexUtil.decodeHex(content));
|
||||||
|
String s = new String(result, "utf-8");
|
||||||
|
return s;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SecretKeySpec getSecretKey(byte[] key) {
|
||||||
|
// 返回生成指定算法密钥生成器的 KeyGenerator 对象
|
||||||
|
KeyGenerator kg = null;
|
||||||
|
try {
|
||||||
|
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
|
||||||
|
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||||||
|
random.setSeed(key);
|
||||||
|
// AES 要求密钥长度为 128
|
||||||
|
kg.init(128, random);
|
||||||
|
// 生成一个密钥
|
||||||
|
SecretKey secretKey = kg.generateKey();
|
||||||
|
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
|
||||||
|
} catch (NoSuchAlgorithmException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,61 +1,18 @@
|
|||||||
/**
|
|
||||||
|
|
||||||
*
|
|
||||||
|
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.geedge.util;
|
package net.geedge.util;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import cn.hutool.core.util.HexUtil;
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.apache.ibatis.mapping.DatabaseIdProvider;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.log.Log;
|
import cn.hutool.log.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 常量
|
* 常量
|
||||||
*
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public class Constant {
|
public class Constant {
|
||||||
private final static Log logger = Log.get();
|
|
||||||
|
private final static Log log = Log.get();
|
||||||
public static Boolean rollBack = false;
|
|
||||||
/**
|
/**
|
||||||
* 当前数据库类型
|
* aes 对称加密 密钥
|
||||||
*/
|
*/
|
||||||
public static final String DB_TYPE;
|
public static final byte[] AES_SECRET_KEY = HexUtil.decodeHex("bde5430614b21baf1c53bd6f616d1a39");
|
||||||
public static final String DATABASE_NAME;
|
|
||||||
public static final String ORACLE = "oracle";
|
|
||||||
public static final String MYSQL = "mysql";
|
|
||||||
public static final String POSTGRESQL = "postgresql";
|
|
||||||
|
|
||||||
|
|
||||||
static {
|
|
||||||
DatabaseIdProvider databaseIdProvider = SpringContextUtils.getBean("getDatabaseIdProvider", DatabaseIdProvider.class);
|
|
||||||
DataSource dataSource = SpringContextUtils.getBean("dataSource",DataSource.class);
|
|
||||||
String databaseId = null;
|
|
||||||
String databaseName=null;
|
|
||||||
try {
|
|
||||||
databaseId = databaseIdProvider.getDatabaseId(dataSource);
|
|
||||||
Connection connection = dataSource.getConnection();
|
|
||||||
DatabaseMetaData metaData = connection.getMetaData();
|
|
||||||
String url = metaData.getURL();
|
|
||||||
if(StrUtil.isNotBlank(url)) {
|
|
||||||
String[] split = StrUtil.split(url, "?");
|
|
||||||
databaseName = StrUtil.subAfter(split[0], "/", true);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
logger.error(e);
|
|
||||||
}
|
|
||||||
DB_TYPE = databaseId;
|
|
||||||
DATABASE_NAME = databaseName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user