fix: NEZ-2203 从 /opt/nezha/nz-web/config/nezha.properties 获取数据源信息

1. 升级之后对 nezha.properties database.pin 加密
This commit is contained in:
shizhendong
2022-09-29 15:51:26 +08:00
parent 21e629ec54
commit 90f33992d5
5 changed files with 227 additions and 55 deletions

View File

@@ -1,10 +1,11 @@
package net.geedge;
import org.springframework.beans.factory.annotation.Value;
import cn.hutool.setting.dialect.Props;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.util.Properties;
@SpringBootApplication
public class TransferApplication {
@@ -13,4 +14,11 @@ public class TransferApplication {
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;
}
}

View 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"));
}
}

View File

@@ -1,7 +1,10 @@
package net.geedge.handler;
import cn.hutool.log.Log;
import cn.hutool.setting.dialect.Props;
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.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
@@ -10,7 +13,9 @@ import org.springframework.stereotype.Component;
import java.util.List;
/**
* 此类用于数据同步完成后 清除无用表
* 此类用于数据同步完成后
* 1. 清除无用表
* 2. 修改 nezha.properties 密码加密
* @author admin
*
*/
@@ -41,6 +46,20 @@ public class AfterHandler implements CommandLineRunner {
}
sqlDao.execute(sb.toString());
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-----------------------");
}

View 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;
}
}

View File

@@ -1,61 +1,18 @@
/**
*
*
*/
package net.geedge.util;
import java.sql.Connection;
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.core.util.HexUtil;
import cn.hutool.log.Log;
/**
* 常量
*
*/
public class Constant {
private final static Log logger = Log.get();
public static Boolean rollBack = false;
/**
* 当前数据库类型
*/
public static final String DB_TYPE;
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;
}
private final static Log log = Log.get();
/**
* aes 对称加密 密钥
*/
public static final byte[] AES_SECRET_KEY = HexUtil.decodeHex("bde5430614b21baf1c53bd6f616d1a39");
}