first commit
This commit is contained in:
9
comm/DB/bin/config/db.properties
Executable file
9
comm/DB/bin/config/db.properties
Executable file
@@ -0,0 +1,9 @@
|
||||
|
||||
#\u5907\u4efd\u6570\u636e\u5e93
|
||||
db.ip=127.0.0.1
|
||||
db.port=6306
|
||||
db.database.name=demo
|
||||
db.username=root
|
||||
db.password=2uVS6UkYyV7Do4JbN9zebDUMoF4w88q3CNxanZ0wEnY%3D
|
||||
db.backup.path=/backup
|
||||
|
||||
15
comm/DB/src/db/Constants.java
Executable file
15
comm/DB/src/db/Constants.java
Executable file
@@ -0,0 +1,15 @@
|
||||
package db;
|
||||
|
||||
public class Constants {
|
||||
|
||||
/**
|
||||
* 备份时间格式
|
||||
*/
|
||||
public final static String DB_BACKUP_TIME_FORMAT = "yyyyMMddHHmmss-SSS";
|
||||
|
||||
/**
|
||||
* File.separator 正则 "\\"
|
||||
*/
|
||||
public static final String FILE_SEPARATOR_REGEX = "\\\\";
|
||||
|
||||
}
|
||||
23
comm/DB/src/db/DBBackup.java
Executable file
23
comm/DB/src/db/DBBackup.java
Executable file
@@ -0,0 +1,23 @@
|
||||
package db;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface DBBackup {
|
||||
|
||||
/**
|
||||
* <p>Description: 数据库备份 </p>
|
||||
*
|
||||
* @param params 参数(若缺省则使用系统默认配置) <pre>
|
||||
* ip -- IP地址
|
||||
* port -- 端口
|
||||
* databaseName -- 数据库名
|
||||
* username -- 用户名
|
||||
* password -- 密码
|
||||
* backupPath -- 备份存储路径</pre>
|
||||
*
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean backup(Map<String, Object> params, OpertProcessListener processListener);
|
||||
|
||||
}
|
||||
15
comm/DB/src/db/DBBackupBeanHandler.java
Executable file
15
comm/DB/src/db/DBBackupBeanHandler.java
Executable file
@@ -0,0 +1,15 @@
|
||||
package db;
|
||||
|
||||
public interface DBBackupBeanHandler {
|
||||
|
||||
/**
|
||||
* @param backupRecordService The backupRecordService to set.
|
||||
*/
|
||||
public void setBackupRecordService(DBBackupRecordService backupRecordService);
|
||||
|
||||
/**
|
||||
* @param operatorEvent The operatorEvent to set.
|
||||
*/
|
||||
public void setOperatorEvent(DBOperatorEvent operatorEvent);
|
||||
|
||||
}
|
||||
25
comm/DB/src/db/DBBackupLock.java
Executable file
25
comm/DB/src/db/DBBackupLock.java
Executable file
@@ -0,0 +1,25 @@
|
||||
package db;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class DBBackupLock {
|
||||
public static final String ALL_DB_LOCK = "ALL_DB_LOCK";
|
||||
private static final Set<String> filter = new HashSet<String>();
|
||||
|
||||
public static boolean add(String lock) {
|
||||
if (!filter.add(lock)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void remove(String lock) {
|
||||
filter.remove(lock);
|
||||
|
||||
}
|
||||
public static boolean getLock(String lock) {
|
||||
return filter.contains(lock);
|
||||
}
|
||||
}
|
||||
172
comm/DB/src/db/DBBackupRecord.java
Executable file
172
comm/DB/src/db/DBBackupRecord.java
Executable file
@@ -0,0 +1,172 @@
|
||||
package db;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import db.util.FileUtil;
|
||||
|
||||
|
||||
public class DBBackupRecord {
|
||||
|
||||
/**
|
||||
* UUID
|
||||
*/
|
||||
private String uuid;
|
||||
|
||||
/**
|
||||
* 备份名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 备份时间
|
||||
*/
|
||||
private Date backupTime;
|
||||
|
||||
/**
|
||||
* 备份文件路径
|
||||
*/
|
||||
private String filePath;
|
||||
|
||||
/**
|
||||
* 备份文件大小(B)
|
||||
*/
|
||||
private Long fileSize;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* Gets the UUID.
|
||||
*
|
||||
* @return Returns the uuid.
|
||||
*/
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the UUID.
|
||||
*
|
||||
* @param uuid The uuid to set.
|
||||
*/
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 备份名称.
|
||||
*
|
||||
* @return Returns the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 备份名称.
|
||||
*
|
||||
* @param name The name to set.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 备份时间.
|
||||
*
|
||||
* @return Returns the backupTime.
|
||||
*/
|
||||
public Date getBackupTime() {
|
||||
return backupTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 备份时间.
|
||||
*
|
||||
* @param backupTime The backupTime to set.
|
||||
*/
|
||||
public void setBackupTime(Date backupTime) {
|
||||
this.backupTime = backupTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 备份文件路径.
|
||||
*
|
||||
* @return Returns the filePath.
|
||||
*/
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 备份文件路径.
|
||||
*
|
||||
* @param filePath The filePath to set.
|
||||
*/
|
||||
public void setFilePath(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 备份文件大小(B).
|
||||
*
|
||||
* @return Returns the fileSize.
|
||||
*/
|
||||
public Long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 备份文件大小(B).
|
||||
*
|
||||
* @param fileSize The fileSize to set.
|
||||
*/
|
||||
public void setFileSize(Long fileSize) {
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 备注.
|
||||
*
|
||||
* @return Returns the description.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 备注.
|
||||
*
|
||||
* @param description The description to set.
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer str = new StringBuffer("\n");
|
||||
str.append("===============================================================================");
|
||||
str.append("\n");
|
||||
str.append("<< ").append(getClass().getSimpleName()).append(" >>");
|
||||
str.append("\n");
|
||||
str.append("-------------------------------------------------------------------------------");
|
||||
str.append("\n");
|
||||
str.append(" UUID: ").append(getUuid());
|
||||
str.append("\n");
|
||||
str.append(" Name: ").append(getName());
|
||||
str.append("\n");
|
||||
str.append(" BackupTime: ").append(getBackupTime());
|
||||
str.append("\n");
|
||||
str.append(" FilePath: ").append(getFilePath());
|
||||
str.append("\n");
|
||||
str.append(" FileSize: ").append(FileUtil.formetFileSize(getFileSize(), null));
|
||||
str.append("\n");
|
||||
str.append(" Description: ").append(getDescription());
|
||||
str.append("\n");
|
||||
str.append("-------------------------------------------------------------------------------");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
57
comm/DB/src/db/DBBackupRecordService.java
Executable file
57
comm/DB/src/db/DBBackupRecordService.java
Executable file
@@ -0,0 +1,57 @@
|
||||
package db;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface DBBackupRecordService {
|
||||
|
||||
/**
|
||||
* <p>Description: 从缓存中获取所有备份记录信息 </p>
|
||||
* @return 备份记录信息集合
|
||||
*/
|
||||
public Collection<DBBackupRecord> findAll();
|
||||
|
||||
/**
|
||||
* <p>Description: 从缓存中获取备份记录 </p>
|
||||
* @param uuid 备份记录ID
|
||||
* @return 备份记录详情
|
||||
*/
|
||||
public DBBackupRecord findByUuid(Serializable uuid);
|
||||
|
||||
/**
|
||||
* <p>Description: 添加备份记录信息,要同步添加缓存 </p>
|
||||
* @param record 备份记录信息
|
||||
*/
|
||||
public void add(DBBackupRecord record);
|
||||
|
||||
/**
|
||||
* <p>Description: 删除备份记录,要同步删除缓存和文件 </p>
|
||||
* @param uuid 备份记录ID
|
||||
*/
|
||||
public void delete(Serializable uuid);;
|
||||
|
||||
/**
|
||||
* <p>Description: 批量删除备份,要同步删除缓存和文件 </p>
|
||||
* @param ids 备份记录ID数组
|
||||
* @return 删除记录条数
|
||||
*/
|
||||
public int deleteByIds(Serializable[] ids);
|
||||
|
||||
/**
|
||||
* <p>Description: 获取最大备份记录保存限值 </p>
|
||||
* @return 最大备份记录限值
|
||||
*/
|
||||
public Integer getMaxLimitNum();
|
||||
|
||||
/**
|
||||
* <p>Description: 设置最大备份记录保存限值 </p>
|
||||
* @param limitNum 限值
|
||||
*/
|
||||
public void setMaxLimitNum(Integer limitNum);
|
||||
|
||||
/**
|
||||
* <p>Description: 初始化 </p>
|
||||
*/
|
||||
public void initialize();
|
||||
|
||||
}
|
||||
80
comm/DB/src/db/DBBeanFactory.java
Executable file
80
comm/DB/src/db/DBBeanFactory.java
Executable file
@@ -0,0 +1,80 @@
|
||||
package db;
|
||||
|
||||
import db.backup.internal.MysqlBackupImpl;
|
||||
import db.restore.MysqlRestoreImpl;
|
||||
import db.util.ConfigUtils;
|
||||
|
||||
public class DBBeanFactory {
|
||||
|
||||
/**
|
||||
* <p>Description: 创建DBBackup实例 </p>
|
||||
*
|
||||
* @param backupRecordService 备份记录信息管理接口
|
||||
* @param operatorEvent 数据库操作事件
|
||||
* @return DBBackup实例
|
||||
*/
|
||||
public static Object buildBackupBean(DBBackupRecordService backupRecordService, //
|
||||
DBOperatorEvent operatorEvent) {
|
||||
SupportDBTypeEnum dbType = ConfigUtils.getCurrentDBType(); // 当前数据库类型
|
||||
DBBackup backupService = null;
|
||||
switch (dbType) {
|
||||
case mysql:
|
||||
backupService = new MysqlBackupImpl();
|
||||
break;
|
||||
// case oracle:
|
||||
// backupService = new OracleBackupImpl();
|
||||
// break;
|
||||
// case postgre:
|
||||
// backupService = new PostgreBackupImpl();
|
||||
// break;
|
||||
// case sqlserver:
|
||||
// backupService = new SQLServerBackupImpl();
|
||||
// break;
|
||||
}
|
||||
|
||||
if (backupService == null) {
|
||||
throw new IllegalArgumentException("The DB backupService can not be NULL");
|
||||
}
|
||||
|
||||
if (backupService instanceof DBBackupBeanHandler) {
|
||||
((DBBackupBeanHandler) backupService).setBackupRecordService(backupRecordService);
|
||||
((DBBackupBeanHandler) backupService).setOperatorEvent(operatorEvent);
|
||||
}
|
||||
return backupService;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 创建DBRestore实例 </p>
|
||||
*
|
||||
* @param operatorEvent 数据库操作事件
|
||||
* @return DBRestore实例
|
||||
*/
|
||||
public static Object buildRestoreBean(DBOperatorEvent operatorEvent) {
|
||||
SupportDBTypeEnum dbType = ConfigUtils.getCurrentDBType(); // 当前数据库类型
|
||||
DBRestore restoreService = null;
|
||||
switch (dbType) {
|
||||
case mysql:
|
||||
restoreService = new MysqlRestoreImpl();
|
||||
break;
|
||||
// case oracle:
|
||||
// restoreService = new OracleRestoreImpl();
|
||||
// break;
|
||||
// case postgre:
|
||||
// restoreService = new PostgreRestoreImpl();
|
||||
// break;
|
||||
// case sqlserver:
|
||||
// restoreService = new SQLServerRestoreImpl();
|
||||
// break;
|
||||
}
|
||||
|
||||
if (restoreService == null) {
|
||||
throw new IllegalArgumentException("The DB restoreService can not be NULL");
|
||||
}
|
||||
|
||||
if (restoreService instanceof DBRestoreBeanHandler) {
|
||||
((DBRestoreBeanHandler) restoreService).setOperatorEvent(operatorEvent);
|
||||
}
|
||||
return restoreService;
|
||||
}
|
||||
|
||||
}
|
||||
35
comm/DB/src/db/DBOperatorEvent.java
Executable file
35
comm/DB/src/db/DBOperatorEvent.java
Executable file
@@ -0,0 +1,35 @@
|
||||
package db;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DBOperatorEvent {
|
||||
|
||||
/**
|
||||
* 开始备份前
|
||||
* @param params 参数
|
||||
*/
|
||||
public void beforeBackup(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 备份后事件
|
||||
* @param record 备份记录
|
||||
* @param params 参数
|
||||
*/
|
||||
public void afterBackup(DBBackupRecord record, Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 数据库还原操作前
|
||||
* @param file 备份文件
|
||||
* @param params 参数
|
||||
*/
|
||||
public void beforeRestore(File file, Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 数据库还原操作后
|
||||
* @param file 备份文件
|
||||
* @param params 参数
|
||||
*/
|
||||
public void afterRestore(File file, Map<String, Object> params);
|
||||
|
||||
}
|
||||
41
comm/DB/src/db/DBRestore.java
Executable file
41
comm/DB/src/db/DBRestore.java
Executable file
@@ -0,0 +1,41 @@
|
||||
package db;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DBRestore {
|
||||
|
||||
/**
|
||||
* <p>Description: 从文件还原数据库 </p>
|
||||
* @param file 待还原的文件
|
||||
* @param params 参数(若缺省则使用系统默认配置)<pre>
|
||||
* ip -- IP地址
|
||||
* port -- 端口
|
||||
* databaseName -- 数据库名
|
||||
* username -- 用户名
|
||||
* password -- 密码</pre>
|
||||
*
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean restore(File file, Map<String, Object> params, OpertProcessListener processListener);
|
||||
|
||||
/**
|
||||
* <p>Description: 从文件还原数据库 </p>
|
||||
* @param filePath 待还原的文件路径
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean restore(String filePath, Map<String, Object> params, OpertProcessListener processListener);
|
||||
|
||||
/**
|
||||
<p>Description: 从备份记录还原数据库 </p>
|
||||
* @param record 备份记录
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean restore(DBBackupRecord record, Map<String, Object> params, OpertProcessListener processListener);
|
||||
|
||||
}
|
||||
10
comm/DB/src/db/DBRestoreBeanHandler.java
Executable file
10
comm/DB/src/db/DBRestoreBeanHandler.java
Executable file
@@ -0,0 +1,10 @@
|
||||
package db;
|
||||
|
||||
public interface DBRestoreBeanHandler {
|
||||
|
||||
/**
|
||||
* @param operatorEvent The operatorEvent to set.
|
||||
*/
|
||||
public void setOperatorEvent(DBOperatorEvent operatorEvent);
|
||||
|
||||
}
|
||||
31
comm/DB/src/db/OpertProcessListener.java
Executable file
31
comm/DB/src/db/OpertProcessListener.java
Executable file
@@ -0,0 +1,31 @@
|
||||
package db;
|
||||
|
||||
import db.support.MessageOutputListener;
|
||||
|
||||
public interface OpertProcessListener {
|
||||
|
||||
/**
|
||||
* <p>Description: 输出信息监听器 </p>
|
||||
*
|
||||
* @return 输出信息监听器
|
||||
*/
|
||||
public MessageOutputListener getOutputListener();
|
||||
|
||||
/**
|
||||
* <p>Description: 操作结束 </p>
|
||||
*/
|
||||
public void onExit();
|
||||
|
||||
/**
|
||||
* <p>Description: 备份操作中止 </p>
|
||||
*/
|
||||
public void onInterrupt();
|
||||
|
||||
/**
|
||||
* <p>Description: 操作过程是否结束 </p>
|
||||
*
|
||||
* @return 是否结束
|
||||
*/
|
||||
public boolean isFinish();
|
||||
|
||||
}
|
||||
130
comm/DB/src/db/PropertiesUtilDB.java
Executable file
130
comm/DB/src/db/PropertiesUtilDB.java
Executable file
@@ -0,0 +1,130 @@
|
||||
package db;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* 读取Properties综合类,默认绑定到classpath下的config.properties文件。
|
||||
*/
|
||||
public class PropertiesUtilDB {
|
||||
private static Logger logger = LogManager.getLogger(PropertiesUtilDB.class);
|
||||
private static String CONFIG_FILENAME = "config/db.properties";
|
||||
private static Properties prop = null;
|
||||
|
||||
public PropertiesUtilDB() {
|
||||
if (prop == null) {
|
||||
loadProperties();
|
||||
}
|
||||
};
|
||||
|
||||
private synchronized static void loadProperties() {
|
||||
byte buff[] = null;
|
||||
try {
|
||||
// Open the props file
|
||||
InputStream is = PropertiesUtilDB.class.getResourceAsStream("/" + CONFIG_FILENAME);
|
||||
prop = new Properties();
|
||||
// Read in the stored properties
|
||||
prop.load(is);
|
||||
} catch (Exception e) {
|
||||
System.err.println("读取配置文件失败!!!");
|
||||
prop = null;
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到属性值
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getProperty(String key) {
|
||||
if (prop == null) {
|
||||
loadProperties();
|
||||
}
|
||||
|
||||
String value = prop.getProperty(key);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到内容包含汉字的属性值
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getGBKProperty(String key) {
|
||||
String value = getProperty(key);
|
||||
try {
|
||||
value = new String(value.getBytes("ISO8859-1"), "GBK");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到属性值,
|
||||
*
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public static String getProperty(String key, String defaultValue) {
|
||||
if (prop == null) {
|
||||
loadProperties();
|
||||
}
|
||||
|
||||
String value = prop.getProperty(key, defaultValue);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到内容包含汉字的属性值,如果不存在则使用默认值
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getGBKProperty(String key, String defaultValue) {
|
||||
try {
|
||||
defaultValue = new String(defaultValue.getBytes("GBK"), "ISO8859-1");
|
||||
String value = getProperty(key, defaultValue);
|
||||
value = new String(value.getBytes("ISO8859-1"), "GBK");
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.trim();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUTFProperty(String key, String defaultValue) {
|
||||
try {
|
||||
defaultValue = new String(defaultValue.getBytes("UTF-8"), "ISO8859-1");
|
||||
String value = getProperty(key, defaultValue);
|
||||
value = new String(value.getBytes("ISO8859-1"), "UTF-8");
|
||||
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.trim();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
comm/DB/src/db/SupportDBTypeEnum.java
Executable file
52
comm/DB/src/db/SupportDBTypeEnum.java
Executable file
@@ -0,0 +1,52 @@
|
||||
package db;
|
||||
|
||||
public enum SupportDBTypeEnum {
|
||||
/**
|
||||
* MySQL数据库
|
||||
*/
|
||||
mysql,
|
||||
|
||||
/**
|
||||
* Oracle数据库
|
||||
*/
|
||||
oracle,
|
||||
|
||||
/**
|
||||
* Postgre数据库
|
||||
*/
|
||||
postgre,
|
||||
|
||||
/**
|
||||
* SQLServer数据库
|
||||
*/
|
||||
sqlserver;
|
||||
|
||||
/**
|
||||
* @param type 数据库类型名
|
||||
* @return support DBType
|
||||
*/
|
||||
public static SupportDBTypeEnum getEnum(String type) {
|
||||
if (type == null || "".equals(type = type.trim())) {
|
||||
throw new IllegalArgumentException("The database type can not be NULL");
|
||||
}
|
||||
|
||||
SupportDBTypeEnum result = null;
|
||||
try {
|
||||
result = SupportDBTypeEnum.valueOf(type);
|
||||
return result;
|
||||
} catch (Throwable e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
for (SupportDBTypeEnum supportType : SupportDBTypeEnum.values()) {
|
||||
if (supportType.name().equalsIgnoreCase(type)) {
|
||||
return supportType;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException("The database type with name '" + type + "' is not support");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
234
comm/DB/src/db/backup/internal/AbstractBackupImpl.java
Executable file
234
comm/DB/src/db/backup/internal/AbstractBackupImpl.java
Executable file
@@ -0,0 +1,234 @@
|
||||
package db.backup.internal;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import db.Constants;
|
||||
import db.DBBackup;
|
||||
import db.DBBackupBeanHandler;
|
||||
import db.DBBackupRecord;
|
||||
import db.DBBackupRecordService;
|
||||
import db.DBOperatorEvent;
|
||||
import db.OpertProcessListener;
|
||||
import db.support.DBBackupRecordServiceImpl;
|
||||
import db.util.FileUtil;
|
||||
import db.util.PathUtil;
|
||||
import db.util.UUIDGenerator;
|
||||
import kernel.util.DateUtils;
|
||||
import kernel.util.StringUtils;
|
||||
|
||||
|
||||
public abstract class AbstractBackupImpl implements DBBackup, DBBackupBeanHandler {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 默认备份路径
|
||||
*/
|
||||
protected final static String DEFAULT_BACKUP_PATH = PathUtil.getDbBackupPath();
|
||||
|
||||
/**
|
||||
* 事件通知
|
||||
*/
|
||||
protected DBOperatorEvent operatorEvent;
|
||||
|
||||
/**
|
||||
* 数据库备份记录信息管理接口
|
||||
*/
|
||||
protected DBBackupRecordService backupRecordService = new DBBackupRecordServiceImpl();
|
||||
|
||||
@Override
|
||||
public boolean backup(Map<String, Object> params, OpertProcessListener processListener) {
|
||||
if (params == null) {
|
||||
params = new HashMap<String, Object>();
|
||||
}
|
||||
params = parserMapParams(params); // 解析参数
|
||||
|
||||
// operatorEvent.beforeBackup(params); // 备份前事件通知
|
||||
|
||||
boolean result = false;
|
||||
DBBackupRecord record = null;
|
||||
backupRecordService = new DBBackupRecordServiceImpl();
|
||||
try {
|
||||
if (doEnvironmentCheck(params, processListener)) {
|
||||
Date backupTime = new Date(); // 备份时间
|
||||
params.put("backupTime", backupTime);
|
||||
|
||||
String backupName = (String) params.get("backupName"); // 备份名称
|
||||
if (backupName == null) {
|
||||
String databaseName = (String) params.get("databaseName");
|
||||
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
|
||||
backupName = databaseName + "_" + sdf.format(backupTime);
|
||||
params.put("backupName", backupName);
|
||||
}
|
||||
|
||||
result = doBackup(params, processListener); // 执行备份操作
|
||||
|
||||
record = createNewBackupRecord(params); // 新建备份记录
|
||||
backupRecordService.add(record); // 保存备份文件信息
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
result = false;
|
||||
logger.error("backup database error", e);
|
||||
// throw new FastFailException(e);
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
String msg = "Finished - " + (result ? "Successfully" : "Failed");
|
||||
try {
|
||||
onOutputAndLog(processListener, msg, Level.INFO);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (processListener != null) {
|
||||
processListener.onExit();
|
||||
}
|
||||
|
||||
clearAfterBackup(params); // 备份后清理
|
||||
}
|
||||
|
||||
params.put("result", result); // 结果
|
||||
// operatorEvent.afterBackup(record, params); // 备份后事件通知
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 备份清理工作(清除临时目录、不完整备份文件等操作) </p>
|
||||
* <p>Create Time: 2013-2-20 </p>
|
||||
* @author weiminghua
|
||||
* @param params 参数
|
||||
*/
|
||||
protected void clearAfterBackup(Map<String, Object> params) {
|
||||
// default do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份文件后缀
|
||||
* @return 备份文件后缀名
|
||||
*/
|
||||
protected abstract String getBackupFileSuffix();
|
||||
|
||||
/**
|
||||
* 解析参数
|
||||
*
|
||||
* @param params 参数
|
||||
* @return 参数
|
||||
*/
|
||||
protected abstract Map<String, Object> parserMapParams(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 运行环境检测
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
protected abstract boolean doEnvironmentCheck(Map<String, Object> params, OpertProcessListener processListener);
|
||||
|
||||
/**
|
||||
* 执行备份
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
* @throws InterruptedException 中断异常
|
||||
*/
|
||||
protected abstract boolean doBackup(Map<String, Object> params, OpertProcessListener processListener)
|
||||
throws InterruptedException;
|
||||
|
||||
/**
|
||||
* @param operatorEvent The operatorEvent to set.
|
||||
*/
|
||||
public void setOperatorEvent(DBOperatorEvent operatorEvent) {
|
||||
this.operatorEvent = operatorEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param backupRecordService The backupRecordService to set.
|
||||
*/
|
||||
public void setBackupRecordService(DBBackupRecordService backupRecordService) {
|
||||
this.backupRecordService = backupRecordService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成备份记录
|
||||
* @param params 参数
|
||||
* @return 备份记录
|
||||
*/
|
||||
protected DBBackupRecord createNewBackupRecord(Map<String, Object> params) {
|
||||
DBBackupRecord record = new DBBackupRecord();
|
||||
record.setUuid(UUIDGenerator.getUUID());
|
||||
String backupName = (String) params.get("backupName");
|
||||
record.setName(backupName);
|
||||
record.setBackupTime((Date) params.get("backupTime")); // 备份时间
|
||||
String description = (String) params.get("description"); // 备份描述
|
||||
record.setDescription(description);
|
||||
|
||||
String backupPath = (String) params.get("backupPath"); // 备份存储路径
|
||||
String filePath = backupPath + "/" + backupName + getBackupFileSuffix(); // 备份文件路径
|
||||
record.setFilePath(filePath);
|
||||
try {
|
||||
record.setFileSize(FileUtil.getFileSize(filePath));
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.error("get backup file[" + filePath + "] size error");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出监听,同时添加日志信息
|
||||
* @param processListener 过程监听
|
||||
* @param msg 日志信息
|
||||
* @param log4jLevel 日志级别
|
||||
* @throws InterruptedException 备份中断异常
|
||||
*/
|
||||
protected void onOutputAndLog(OpertProcessListener processListener, String msg, Level log4jLevel)
|
||||
throws InterruptedException {
|
||||
if (StringUtils.isNullOrEmpty(msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (processListener != null) {
|
||||
if (processListener.isFinish()) {
|
||||
throw new InterruptedException("interrupt databse backup"); // 备份中断
|
||||
}
|
||||
|
||||
if (processListener.getOutputListener() != null) {
|
||||
processListener.getOutputListener().onOutput(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (log4jLevel == null) {
|
||||
try {
|
||||
Thread.sleep(200); // 延迟加载信息
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 输出日志信息
|
||||
if (Level.ERROR.equals(log4jLevel)) {
|
||||
logger.error(msg);
|
||||
}
|
||||
else if (Level.WARN.equals(log4jLevel)) {
|
||||
logger.warn(msg);
|
||||
}
|
||||
else if (Level.INFO.equals(log4jLevel)) {
|
||||
logger.info(msg);
|
||||
}
|
||||
else if (Level.DEBUG.equals(log4jLevel)) {
|
||||
logger.debug(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
302
comm/DB/src/db/backup/internal/MysqlBackupImpl.java
Executable file
302
comm/DB/src/db/backup/internal/MysqlBackupImpl.java
Executable file
@@ -0,0 +1,302 @@
|
||||
package db.backup.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.jcraft.jsch.SftpException;
|
||||
|
||||
import db.Constants;
|
||||
import db.DBBackup;
|
||||
import db.OpertProcessListener;
|
||||
import db.PropertiesUtilDB;
|
||||
import db.util.CMDUtil;
|
||||
import db.util.FileUtil;
|
||||
import db.util.SFTPUtil;
|
||||
import db.util.ZipUtils;
|
||||
import db.util.jdbc.DBTools;
|
||||
import db.util.jdbc.MysqlTools;
|
||||
|
||||
public class MysqlBackupImpl extends AbstractBackupImpl {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@Override
|
||||
protected String getBackupFileSuffix() {
|
||||
return ".zip";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> parserMapParams(Map<String, Object> params) {
|
||||
Assert.notNull(params);
|
||||
// 读取参数
|
||||
if (params.get("ip") == null) {
|
||||
// String ip = System.getProperty(DBPorperties.ENV_IP, MySQLConfig.DEFAULT_IP);
|
||||
String ip = PropertiesUtilDB.getProperty("db.ip");
|
||||
params.put("ip", ip);
|
||||
}
|
||||
|
||||
if (params.get("port") == null) {
|
||||
// String port = System.getProperty(DBPorperties.ENV_PORT, MySQLConfig.DEFAULT_PORT);
|
||||
String port = PropertiesUtilDB.getProperty("db.port");
|
||||
params.put("port", port);
|
||||
}
|
||||
|
||||
if (params.get("databaseName") == null) {
|
||||
// String databaseName = System.getProperty(DBPorperties.ENV_DBNAME, MySQLConfig.DEFAULT_DBNAME);
|
||||
String databaseName = PropertiesUtilDB.getProperty("db.databaseName");
|
||||
params.put("databaseName", databaseName);
|
||||
}
|
||||
|
||||
if (params.get("username") == null) {
|
||||
// String username = System.getProperty(DBPorperties.RUIJIE_JDBC_USERNAME);
|
||||
String username = PropertiesUtilDB.getProperty("db.username");
|
||||
params.put("username", username);
|
||||
}
|
||||
|
||||
if (params.get("password") == null) {
|
||||
// String password = System.getProperty(DBPorperties.RUIJIE_JDBC_PASSWORD);
|
||||
String password = PropertiesUtilDB.getProperty("db.password");
|
||||
params.put("password", password);
|
||||
}
|
||||
|
||||
// 备份存储路径
|
||||
if (params.get("backupPath") == null) {
|
||||
String backupPath = DEFAULT_BACKUP_PATH;
|
||||
params.put("backupPath", backupPath);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doEnvironmentCheck(Map<String, Object> params, OpertProcessListener processListener) {
|
||||
Assert.notNull(params);
|
||||
// TODO:doEnvironmentCheck
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doBackup(Map<String, Object> params, OpertProcessListener processListener)
|
||||
throws InterruptedException {
|
||||
Assert.notNull(params);
|
||||
onOutputAndLog(processListener, "Starting backup...", Level.INFO);
|
||||
|
||||
String backupPath = (String) params.get("backupPath"); // 备份路径
|
||||
String backupName = (String) params.get("backupName");
|
||||
String realBackupPath = backupPath + "/" + backupName; // 实际备份路径
|
||||
FileUtil.deleteDir(realBackupPath, false); // 删除旧备份
|
||||
File backUpdir = new File(realBackupPath);
|
||||
if (!backUpdir.exists()) {
|
||||
backUpdir.mkdirs();
|
||||
}
|
||||
|
||||
// 备份数据库结构
|
||||
// backupDBStruct(params, realBackupPath, processListener);
|
||||
|
||||
// 备份数据库表数据
|
||||
// backupDBData(params, realBackupPath, processListener);
|
||||
|
||||
backupDBDataByShell(params, realBackupPath, processListener);
|
||||
|
||||
// 压缩备份文件
|
||||
String zipName = backupName + getBackupFileSuffix(); // 备份文件名
|
||||
String filePath = backupPath + "/" + zipName;
|
||||
ZipUtils.createZip(filePath, realBackupPath);
|
||||
// String zip="zip -m "+filePath+" "+realBackupPath;
|
||||
sftp(filePath);
|
||||
// onOutputAndLog(processListener, "Finished - Successfully", Level.INFO);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearAfterBackup(Map<String, Object> params) {
|
||||
String backupPath = (String) params.get("backupPath"); // 备份路径
|
||||
String backupName = (String) params.get("backupName"); // 备份名称
|
||||
String realBackupPath = backupPath + "/" + backupName;
|
||||
|
||||
// 生成压缩文件后,删除临时目录
|
||||
FileUtil.deleteDir(realBackupPath, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出数据库结构
|
||||
* @param params 参数
|
||||
* @param realPath 实际备份路径
|
||||
* @param processListener 监听器
|
||||
* @throws InterruptedException 中断异常
|
||||
*/
|
||||
private void backupDBStruct(Map<String, Object> params, String realPath, OpertProcessListener processListener)
|
||||
throws InterruptedException {
|
||||
onOutputAndLog(processListener, "backup database struct...", Level.INFO);
|
||||
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
|
||||
|
||||
cmdBuf.append(" -h ").append((String) params.get("ip"));
|
||||
cmdBuf.append(" -P ").append((String) params.get("port"));
|
||||
cmdBuf.append(" --user=").append((String) params.get("username"));
|
||||
cmdBuf.append(" --password=").append((String) params.get("password"));
|
||||
cmdBuf.append(" --opt "); // 同--quick --add-drop-table --add-locks --extended-insert --lock-tables。
|
||||
cmdBuf.append(" --no-data "); // 不备份表数据
|
||||
// cmdBuf.append(" --add-drop-database "); //
|
||||
|
||||
cmdBuf.append(" --result-file=")//
|
||||
.append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
|
||||
.append("/db_struct.sql");
|
||||
|
||||
String databaseName = (String) params.get("databaseName");
|
||||
cmdBuf.append(" ").append(databaseName);
|
||||
|
||||
try {
|
||||
// if (processListener == null || processListener.getOutputListener() == null) {
|
||||
// RuntimeExecutorResult result = RuntimeExecutor.execute(cmdBuf.toString(), "GB2312");
|
||||
// if (logger.isDebugEnabled()) {
|
||||
// logger.debug(result.getOutput());
|
||||
// logger.debug(result.getError());
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// MessageOutputListener outputListener = new MessageOutputListener();
|
||||
// RuntimeExecutor.execute(cmdBuf.toString(), "GB2312", outputListener);
|
||||
// while (!outputListener.isFinish()) {
|
||||
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
|
||||
// }
|
||||
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
|
||||
// }
|
||||
logger.info(cmdBuf.toString());
|
||||
String cmdResult = CMDUtil.runCMD(cmdBuf.toString());
|
||||
logger.info("result:"+cmdResult);
|
||||
} catch (Exception e) {
|
||||
logger.error("backup DataBase Struct error");
|
||||
// throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 导出数据库结构
|
||||
* @param params 参数
|
||||
* @param realPath 实际备份路径
|
||||
* @param processListener 监听器
|
||||
* @throws InterruptedException 中断异常
|
||||
*/
|
||||
private String backupDBDataByShell(Map<String, Object> params, String realPath, OpertProcessListener processListener)
|
||||
throws InterruptedException {
|
||||
onOutputAndLog(processListener, "backup database struct...", Level.INFO);
|
||||
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
|
||||
|
||||
cmdBuf.append(" -h ").append((String) params.get("ip"));
|
||||
cmdBuf.append(" -P ").append((String) params.get("port"));
|
||||
cmdBuf.append(" -u").append((String) params.get("username"));
|
||||
cmdBuf.append(" -p").append("'"+(String) params.get("password")+"'");
|
||||
cmdBuf.append(" ").append((String) params.get("databaseName"));
|
||||
// cmdBuf.append(" --opt "); // 同--quick --add-drop-table --add-locks --extended-insert --lock-tables。
|
||||
// cmdBuf.append(" --no-data "); // 不备份表数据
|
||||
// cmdBuf.append(" --add-drop-database "); //
|
||||
|
||||
cmdBuf.append(" > ")//
|
||||
.append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
|
||||
.append("/home") // 处理空格
|
||||
.append("//")
|
||||
.append((String) params.get("databaseName"))
|
||||
.append(".sql");
|
||||
|
||||
// String databaseName = (String) params.get("databaseName");
|
||||
// cmdBuf.append(" ").append(databaseName);
|
||||
|
||||
try {
|
||||
// if (processListener == null || processListener.getOutputListener() == null) {
|
||||
// RuntimeExecutorResult result = RuntimeExecutor.execute(cmdBuf.toString(), "GB2312");
|
||||
// if (logger.isDebugEnabled()) {
|
||||
// logger.debug(result.getOutput());
|
||||
// logger.debug(result.getError());
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// MessageOutputListener outputListener = new MessageOutputListener();
|
||||
// RuntimeExecutor.execute(cmdBuf.toString(), "GB2312", outputListener);
|
||||
// while (!outputListener.isFinish()) {
|
||||
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
|
||||
// }
|
||||
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
|
||||
// }
|
||||
logger.info(cmdBuf.toString());
|
||||
String cmdResult = CMDUtil.runCMD(cmdBuf.toString());
|
||||
logger.info("result:"+cmdResult);
|
||||
} catch (Exception e) {
|
||||
logger.error("backup DataBase error");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return cmdBuf.toString();
|
||||
}
|
||||
/**
|
||||
* 导出数据
|
||||
* @param params 参数
|
||||
* @param realPath 实际备份路径
|
||||
* @param processListener 监听器
|
||||
* @throws InterruptedException 中断异常
|
||||
*/
|
||||
private void backupDBData(Map<String, Object> params, String realPath, OpertProcessListener processListener)
|
||||
throws InterruptedException {
|
||||
onOutputAndLog(processListener, "Prepare writing data...", Level.INFO);
|
||||
|
||||
String ip = (String) params.get("ip");
|
||||
String port = (String) params.get("port");
|
||||
String databaseName = (String) params.get("databaseName");
|
||||
String username = (String) params.get("username");
|
||||
String password = (String) params.get("password");
|
||||
|
||||
// 获取所有数据库表
|
||||
List<String> tables = MysqlTools.findAllDBTables(ip, port, databaseName, username, password);
|
||||
|
||||
onOutputAndLog(processListener, "Writing data...", Level.INFO);
|
||||
String rootPath = realPath.replaceAll(Constants.FILE_SEPARATOR_REGEX, "/");
|
||||
|
||||
BasicDataSource ds = MysqlTools.createDataSource(ip, port, databaseName, username, password);
|
||||
JdbcTemplate jt = new JdbcTemplate(ds);
|
||||
for (int index = 0; index < tables.size(); index++) {
|
||||
String tableName = tables.get(index);
|
||||
String fileName = rootPath + "/" + tableName + ".txt";
|
||||
|
||||
onOutputAndLog(processListener, "Writing table " + tableName + " data...", Level.INFO);
|
||||
StringBuffer sqlBuf = new StringBuffer();
|
||||
sqlBuf.append("select * from ").append(tableName);
|
||||
sqlBuf.append(" INTO OUTFILE \"").append(fileName).append("\" ");
|
||||
sqlBuf.append(" FIELDS TERMINATED BY ',' ENCLOSED BY '\\\"'");
|
||||
jt.execute(sqlBuf.toString());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void sftp(String filePath) {
|
||||
String sftpBackupPath= PropertiesUtilDB.getProperty("sftp.backup.path");
|
||||
String sftpUsername= PropertiesUtilDB.getProperty("sftp.username");
|
||||
String sftpPassword= PropertiesUtilDB.getProperty("sftp.password");
|
||||
String sftpIp= PropertiesUtilDB.getProperty("sftp.ip");
|
||||
int sftpPort= Integer.valueOf(PropertiesUtilDB.getProperty("sftp.port"));
|
||||
SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
|
||||
sftp.login(SFTPUtil.SFTP);
|
||||
try {
|
||||
sftp.upload(sftpBackupPath, filePath);
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (SftpException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
sftp.logout();
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
DBBackup dbBack = new MysqlBackupImpl();
|
||||
dbBack.backup(null, null);
|
||||
}
|
||||
}
|
||||
67
comm/DB/src/db/job/BackupJob.java
Executable file
67
comm/DB/src/db/job/BackupJob.java
Executable file
@@ -0,0 +1,67 @@
|
||||
package db.job;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import db.DBBackupLock;
|
||||
import db.util.BackupUtil;
|
||||
import kernel.util.DateUtils;
|
||||
import project.log.SysLogService;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class BackupJob {
|
||||
private Logger log = LoggerFactory.getLogger(BackupJob.class);
|
||||
protected SysLogService sysLogService;
|
||||
protected SysparaService sysparaService;
|
||||
|
||||
public void taskJob() {
|
||||
try {
|
||||
// log.info("BackupJob taskJob start,time:"+DateUtils.dateToStr(new Date(), DateUtils.DF_yyyyMMddHHmmss)+",isBackup:"+isBackup()+",lock:"+DBBackupLock.getLock(DBBackupLock.ALL_DB_LOCK));
|
||||
//未被锁
|
||||
if(isBackup() && !DBBackupLock.getLock(DBBackupLock.ALL_DB_LOCK)) {
|
||||
BackupUtil.backupPart(sysLogService,sysparaService);
|
||||
}
|
||||
log.info("BackupJob taskJob end");
|
||||
}catch (Throwable t) {
|
||||
log.error("BackupJob taskJob fail t:"+t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前是否执行局部备份,true:开启,false:不开启
|
||||
* @return
|
||||
*/
|
||||
private boolean isBackup() {
|
||||
//例如, 01:55-02:35,04:00-05:08,13:55-14:45 表示多个时间段内不备份
|
||||
try {
|
||||
String not_part_backup_times = sysparaService.find("not_part_backup_times").getValue();
|
||||
String[] times = not_part_backup_times.split(",");
|
||||
Date now = new Date();
|
||||
String nowDate = DateUtils.getDateStr(now);
|
||||
for (int i = 0; i < times.length; i++) {
|
||||
String[] timePart = times[i].split("-");
|
||||
Date startTime = DateUtils.strToDate(nowDate+" "+timePart[0]);
|
||||
Date endTime = DateUtils.strToDate(nowDate+" "+timePart[1]);
|
||||
if(now.after(startTime)&&now.before(endTime)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
log.error("BackupJob isBackup fail,e:",e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public void setSysLogService(SysLogService sysLogService) {
|
||||
this.sysLogService = sysLogService;
|
||||
}
|
||||
|
||||
public void setSysparaService(SysparaService sysparaService) {
|
||||
this.sysparaService = sysparaService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
95
comm/DB/src/db/map/CacheMap.java
Executable file
95
comm/DB/src/db/map/CacheMap.java
Executable file
@@ -0,0 +1,95 @@
|
||||
package db.map;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class CacheMap<K, V> {
|
||||
|
||||
/**
|
||||
* map cache
|
||||
*/
|
||||
private final Map<K, V> map = Collections.synchronizedMap(new ConcurrentHashMap<K, V>());
|
||||
|
||||
// private final Map<K, V> map = new ConcurrentHashMap<K, V>();
|
||||
|
||||
/**
|
||||
* Associates the specified value with the specified key in this map
|
||||
*
|
||||
* @param key key with which the specified value is to be associated
|
||||
* @param value value to be associated with the specified key
|
||||
*/
|
||||
public void put(K key, V value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the mapping for a key from this map if it is present
|
||||
*
|
||||
* @param key key whose mapping is to be removed from the map
|
||||
*/
|
||||
public void remove(K key) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of key-value mappings in this map.
|
||||
*
|
||||
* @return the size of map
|
||||
*/
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the mappings from this map.
|
||||
*/
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Collection} view of the values contained in this map.
|
||||
*
|
||||
* @return a collection view of the values contained in this map
|
||||
*/
|
||||
public Collection<V> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a the values contained in this map to a list.
|
||||
*
|
||||
* @return a list of the values contained in this map
|
||||
*/
|
||||
public List<V> valuesCopy() {
|
||||
Collection<V> values = map.values();
|
||||
|
||||
return new ArrayList<V>(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped
|
||||
*
|
||||
* @param key the key whose associated value is to be returned
|
||||
* @return the value to which the specified key is mapped, or
|
||||
* {@code null} if this map contains no mapping for the key
|
||||
*/
|
||||
public V get(K key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key.
|
||||
* @param key key whose presence in this map is to be tested
|
||||
* @return <tt>true</tt> if this map contains a mapping for the specified
|
||||
* key
|
||||
*/
|
||||
public boolean containsKey(K key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
}
|
||||
182
comm/DB/src/db/restore/AbstractRestoreImpl.java
Executable file
182
comm/DB/src/db/restore/AbstractRestoreImpl.java
Executable file
@@ -0,0 +1,182 @@
|
||||
package db.restore;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import db.DBBackupRecord;
|
||||
import db.DBOperatorEvent;
|
||||
import db.DBRestore;
|
||||
import db.DBRestoreBeanHandler;
|
||||
import db.OpertProcessListener;
|
||||
import kernel.util.StringUtils;
|
||||
|
||||
public abstract class AbstractRestoreImpl implements DBRestore, DBRestoreBeanHandler {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 事件通知
|
||||
*/
|
||||
protected DBOperatorEvent operatorEvent;
|
||||
|
||||
/**
|
||||
* 备份文件后缀
|
||||
* @return 备份文件后缀名
|
||||
*/
|
||||
protected abstract String getBackupFileSuffix();
|
||||
|
||||
@Override
|
||||
public boolean restore(File file, Map<String, Object> params, OpertProcessListener processListener) {
|
||||
if (params == null) {
|
||||
params = new HashMap<String, Object>();
|
||||
}
|
||||
params = parserMapParams(params); // 解析参数
|
||||
|
||||
// operatorEvent.beforeRestore(file, params); // 操作前事件通知
|
||||
|
||||
boolean result = false;
|
||||
try {
|
||||
if (doEnvironmentCheck(file, params, processListener)) {
|
||||
result = doResotre(file, params, processListener); // 执行还原操作
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
result = false;
|
||||
logger.error("restore database error", e);
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (processListener != null) {
|
||||
processListener.onExit();
|
||||
}
|
||||
|
||||
clearAfterRestore(file, params); // 还原后清理
|
||||
}
|
||||
|
||||
String msg = "Finished - " + (result ? "Successfully" : "Failed");
|
||||
onOutputAndLog(processListener, msg, (result ? Level.INFO : Level.ERROR));
|
||||
|
||||
params.put("result", result); // 结果
|
||||
// operatorEvent.afterRestore(file, params);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原清理工作(清除临时目录、临时文件等操作
|
||||
* @param file 备份文件
|
||||
* @param params 参数
|
||||
*/
|
||||
protected void clearAfterRestore(File file, Map<String, Object> params) {
|
||||
// default do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restore(String filePath, Map<String, Object> params, OpertProcessListener processListener) {
|
||||
return restore(new File(filePath), params, processListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restore(DBBackupRecord record, Map<String, Object> params, OpertProcessListener processListener) {
|
||||
Assert.isTrue(record != null && record.getFilePath() != null);
|
||||
return restore(new File(record.getFilePath()), params, processListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 解析参数 </p>
|
||||
* <p>Create Time: 2013-2-7 </p>
|
||||
* @author weiminghua
|
||||
* @param params 参数
|
||||
* @return 参数
|
||||
*/
|
||||
protected abstract Map<String, Object> parserMapParams(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 运行环境检测
|
||||
* @param file 待还原的文件
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
protected boolean doEnvironmentCheck(File file, Map<String, Object> params, OpertProcessListener processListener) {
|
||||
Assert.isTrue(params != null && file != null);
|
||||
|
||||
// TODO:doEnvironmentCheck
|
||||
if (!file.exists()) {
|
||||
logger.error("restore database failed for file[" + file.getPath() + "] not exists");
|
||||
return false;
|
||||
}
|
||||
|
||||
String suffix = getBackupFileSuffix();
|
||||
if (-1 == file.getPath().indexOf(suffix)) {
|
||||
logger.error("The file[" + file.getPath() + "] not end of [" + suffix + "]");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行备份
|
||||
* @param file 待还原的文件
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
* @return 结果
|
||||
*/
|
||||
protected abstract boolean doResotre(File file, Map<String, Object> params, OpertProcessListener processListener);
|
||||
|
||||
/**
|
||||
* @param operatorEvent The operatorEvent to set.
|
||||
*/
|
||||
public void setOperatorEvent(DBOperatorEvent operatorEvent) {
|
||||
this.operatorEvent = operatorEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出监听,同时添加日志信息
|
||||
* @param processListener 过程监听
|
||||
* @param msg 日志信息
|
||||
* @param log4jLevel 日志级别
|
||||
*/
|
||||
protected void onOutputAndLog(OpertProcessListener processListener, String msg, Level log4jLevel) {
|
||||
if (StringUtils.isNullOrEmpty(msg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (processListener != null) {
|
||||
// 不支持中断
|
||||
if (processListener.getOutputListener() != null) {
|
||||
processListener.getOutputListener().onOutput(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (log4jLevel == null) {
|
||||
try {
|
||||
Thread.sleep(200); // 延迟加载信息
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 输出日志信息
|
||||
if (Level.ERROR.equals(log4jLevel)) {
|
||||
logger.error(msg);
|
||||
}
|
||||
else if (Level.WARN.equals(log4jLevel)) {
|
||||
logger.warn(msg);
|
||||
}
|
||||
else if (Level.INFO.equals(log4jLevel)) {
|
||||
logger.info(msg);
|
||||
}
|
||||
else if (Level.DEBUG.equals(log4jLevel)) {
|
||||
logger.debug(msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
241
comm/DB/src/db/restore/MysqlRestoreImpl.java
Executable file
241
comm/DB/src/db/restore/MysqlRestoreImpl.java
Executable file
@@ -0,0 +1,241 @@
|
||||
package db.restore;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import db.Constants;
|
||||
import db.DBRestore;
|
||||
import db.OpertProcessListener;
|
||||
import db.PropertiesUtilDB;
|
||||
import db.util.CMDUtil;
|
||||
import db.util.FileUtil;
|
||||
import db.util.ZipUtils;
|
||||
import db.util.jdbc.DBTools;
|
||||
import db.util.jdbc.MysqlTools;
|
||||
|
||||
public class MysqlRestoreImpl extends AbstractRestoreImpl {
|
||||
|
||||
@Override
|
||||
protected String getBackupFileSuffix() {
|
||||
return ".zip";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> parserMapParams(Map<String, Object> params) {
|
||||
Assert.notNull(params);
|
||||
// 读取参数
|
||||
if (params.get("ip") == null) {
|
||||
// String ip = System.getProperty(DBPorperties.ENV_IP, MySQLConfig.DEFAULT_IP);
|
||||
String ip = PropertiesUtilDB.getProperty("db.ip");
|
||||
params.put("ip", ip);
|
||||
}
|
||||
|
||||
if (params.get("port") == null) {
|
||||
// String port = System.getProperty(DBPorperties.ENV_PORT, MySQLConfig.DEFAULT_PORT);
|
||||
String port = PropertiesUtilDB.getProperty("db.port");
|
||||
params.put("port", port);
|
||||
}
|
||||
|
||||
if (params.get("databaseName") == null) {
|
||||
// String databaseName = System.getProperty(DBPorperties.ENV_DBNAME, MySQLConfig.DEFAULT_DBNAME);
|
||||
String databaseName = PropertiesUtilDB.getProperty("db.databaseName");
|
||||
params.put("databaseName", databaseName);
|
||||
}
|
||||
|
||||
if (params.get("username") == null) {
|
||||
// String username = System.getProperty(DBPorperties.RUIJIE_JDBC_USERNAME);
|
||||
String username = PropertiesUtilDB.getProperty("db.username");
|
||||
params.put("username", username);
|
||||
}
|
||||
|
||||
if (params.get("password") == null) {
|
||||
// String password = System.getProperty(DBPorperties.RUIJIE_JDBC_PASSWORD);
|
||||
String password = PropertiesUtilDB.getProperty("db.password");
|
||||
params.put("password", password);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doResotre(File file, Map<String, Object> params, OpertProcessListener processListener) {
|
||||
Assert.notNull(params);
|
||||
onOutputAndLog(processListener, "Starting restore...", Level.INFO);
|
||||
|
||||
String filePath = file.getAbsolutePath();
|
||||
String restorePath = formatFilePath(filePath);
|
||||
FileUtil.deleteDir(restorePath, true);
|
||||
|
||||
// 解压备份文件
|
||||
ZipUtils.unZip(filePath, file.getParent() + File.separator);
|
||||
|
||||
// 删除旧数据
|
||||
// clearOldData(params, processListener);
|
||||
|
||||
// 还原数据库结构
|
||||
// restoreDBStruct(params, restorePath, processListener);
|
||||
|
||||
// 还原数据库表数据
|
||||
restoreDBData(params, restorePath, processListener);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearAfterRestore(File file, Map<String, Object> params) {
|
||||
// 数据库还原后,删除临时目录
|
||||
FileUtil.deleteDir(formatFilePath(file.getAbsolutePath()), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化待还原文件路径
|
||||
* @param filePath 待还原文件路径
|
||||
* @return 路径
|
||||
*/
|
||||
private String formatFilePath(String filePath) {
|
||||
String restorePath = filePath.substring(0, filePath.indexOf(getBackupFileSuffix()));
|
||||
restorePath = restorePath.replaceAll(Constants.FILE_SEPARATOR_REGEX, "/");
|
||||
return restorePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除旧数据(防止数据冲突)
|
||||
* @param params 参数
|
||||
* @param processListener 监听器
|
||||
*/
|
||||
private void clearOldData(Map<String, Object> params, OpertProcessListener processListener) {
|
||||
onOutputAndLog(processListener, "Clear old database data...", Level.INFO);
|
||||
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(DBTools.formatDBClientCmd("mysql", "exe"));
|
||||
cmdBuf.append(" -h ").append((String) params.get("ip"));
|
||||
cmdBuf.append(" -P ").append((String) params.get("port")); // 端口
|
||||
cmdBuf.append(" --user=").append((String) params.get("username")); // 用户名
|
||||
cmdBuf.append(" --password=").append((String) params.get("password")); // 密码
|
||||
// cmdBuf.append(" --verbose -v "); // 详情信息模式
|
||||
|
||||
String dbName = (String) params.get("databaseName");
|
||||
cmdBuf.append(" ").append("-e \"DROP DATABASE IF EXISTS ").append(dbName).append(";");
|
||||
cmdBuf.append("CREATE DATABASE ").append(dbName).append(" DEFAULT CHARACTER SET utf8; \" ");
|
||||
executeRuntimeCmd(cmdBuf.toString(), processListener);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原数据库结构
|
||||
* @param params 参数
|
||||
* @param restorePath 备份文件目录
|
||||
* @param processListener 监听器
|
||||
*/
|
||||
private void restoreDBStruct(Map<String, Object> params, String restorePath, OpertProcessListener processListener) {
|
||||
onOutputAndLog(processListener, "Restore database structs...", Level.INFO);
|
||||
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(DBTools.formatDBClientCmd("mysql", "exe"));
|
||||
cmdBuf.append(" -h ").append((String) params.get("ip"));
|
||||
cmdBuf.append(" -P ").append((String) params.get("port")); // 端口
|
||||
cmdBuf.append(" --user=").append((String) params.get("username")); // 用户名
|
||||
cmdBuf.append(" --password=").append((String) params.get("password")); // 密码
|
||||
// cmdBuf.append(" --verbose -v "); // 详情信息模式
|
||||
|
||||
String databaseName = (String) params.get("databaseName");
|
||||
cmdBuf.append(" ").append(databaseName);
|
||||
cmdBuf.append(" ").append("-e \"SET FOREIGN_KEY_CHECKS=0;");
|
||||
cmdBuf.append("SOURCE ").append(restorePath).append("/db_struct.sql ; \" ");
|
||||
|
||||
executeRuntimeCmd(cmdBuf.toString(), processListener); // 执行CMD
|
||||
|
||||
onOutputAndLog(processListener, "restore Structs finished", Level.DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原数据库数据
|
||||
* @param params 参数
|
||||
* @param restorePath 备份文件目录
|
||||
* @param processListener 监听器
|
||||
*/
|
||||
private void restoreDBData(Map<String, Object> params, String restorePath, OpertProcessListener processListener) {
|
||||
onOutputAndLog(processListener, "Importing Data...", Level.INFO);
|
||||
|
||||
String ip = (String) params.get("ip");
|
||||
String port = (String) params.get("port");
|
||||
String databaseName = (String) params.get("databaseName");
|
||||
String username = (String) params.get("username");
|
||||
String password = (String) params.get("password");
|
||||
|
||||
StringBuffer preCmd = new StringBuffer();
|
||||
preCmd.append(DBTools.formatDBClientCmd("mysql", "exe"));
|
||||
preCmd.append(" -h ").append(ip);
|
||||
preCmd.append(" -P ").append(port); // 端口
|
||||
preCmd.append(" --user=").append(username); // 用户名
|
||||
preCmd.append(" --password=").append(password); // 密码
|
||||
// preCmd.append(" --verbose -v "); // 详情信息模式
|
||||
preCmd.append(" ").append(databaseName);
|
||||
preCmd.append(" ").append("-e ");
|
||||
|
||||
// 获取数据库表
|
||||
List<String> tables = MysqlTools.findAllDBTables(ip, port, databaseName, username, password);
|
||||
for (int index = 0; index < tables.size(); index++) {
|
||||
String tableName = tables.get(index);
|
||||
onOutputAndLog(processListener, "Table Restored: " + tableName, Level.INFO);
|
||||
|
||||
String tableDataFilePath = restorePath + "/" + tableName + ".txt";
|
||||
StringBuilder cmdBuf = new StringBuilder();
|
||||
cmdBuf.append(preCmd);
|
||||
cmdBuf.append(" \"LOCK TABLES " + tableName + " WRITE;"); // 锁表
|
||||
cmdBuf.append("SET FOREIGN_KEY_CHECKS=0;"); // 不进行外键检查
|
||||
|
||||
// 导入表数据
|
||||
cmdBuf.append("LOAD DATA INFILE '");
|
||||
cmdBuf.append(tableDataFilePath).append("'");
|
||||
cmdBuf.append("INTO TABLE ").append(tableName);
|
||||
cmdBuf.append(" FIELDS TERMINATED BY ',' ENCLOSED BY '\\\"';");
|
||||
|
||||
cmdBuf.append(" UNLOCK TABLES;").append(" \" "); // 解锁表
|
||||
// cmdBuf.append("\n");
|
||||
executeRuntimeCmd(cmdBuf.toString(), processListener); // 执行CMD
|
||||
}
|
||||
|
||||
onOutputAndLog(processListener, "Importing Data finished", Level.DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行CMD
|
||||
* @param cmd cmd命令
|
||||
* @param processListener 监听器
|
||||
*/
|
||||
private void executeRuntimeCmd(String cmd, OpertProcessListener processListener) {
|
||||
try {
|
||||
// if (processListener == null || processListener.getOutputListener() == null) {
|
||||
// RuntimeExecutorResult result = RuntimeExecutor.execute(cmd, "GB2312");
|
||||
// if (logger.isDebugEnabled()) {
|
||||
// logger.debug(result.getOutput());
|
||||
// logger.debug(result.getError());
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// MessageOutputListener outputListener = new MessageOutputListener();
|
||||
// RuntimeExecutor.execute(cmd, "GB2312", outputListener);
|
||||
// while (!outputListener.isFinish()) {
|
||||
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
|
||||
// }
|
||||
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
|
||||
// }
|
||||
logger.info(cmd);
|
||||
String cmdResult = CMDUtil.runCMD(cmd);
|
||||
logger.info("result:"+cmdResult);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
DBRestore dbBack = new MysqlRestoreImpl();
|
||||
String filePath = "C:\\e\\backup\\blockchain_nes_20201030161757-734.zip";
|
||||
dbBack.restore(filePath, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
302
comm/DB/src/db/support/DBBackupRecordServiceImpl.java
Executable file
302
comm/DB/src/db/support/DBBackupRecordServiceImpl.java
Executable file
@@ -0,0 +1,302 @@
|
||||
package db.support;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.text.DateFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
|
||||
import db.Constants;
|
||||
import db.DBBackupRecord;
|
||||
import db.DBBackupRecordService;
|
||||
import db.map.CacheMap;
|
||||
import db.util.ConfigUtils;
|
||||
import db.util.HandleXML;
|
||||
import db.util.IOUtil;
|
||||
import kernel.util.DateUtils;
|
||||
|
||||
public class DBBackupRecordServiceImpl implements DBBackupRecordService {
|
||||
|
||||
/**
|
||||
* LOG
|
||||
*/
|
||||
private Logger logger = LogManager.getLogger(this.getClass().getName());
|
||||
|
||||
/**
|
||||
* 备份信息XML存储路径
|
||||
*/
|
||||
private final static String BACKUP_RECORD_XML_PATH = ConfigUtils.getBackupRecordXMLPath();
|
||||
|
||||
/**
|
||||
* 文件锁
|
||||
*/
|
||||
private ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
/**
|
||||
* 备份信息缓存
|
||||
*/
|
||||
private static CacheMap<Serializable, DBBackupRecord> BKRECORD_CACHE = new CacheMap<Serializable, DBBackupRecord>();
|
||||
|
||||
/**
|
||||
* 备份文件保存个数最大限值
|
||||
*/
|
||||
private static Integer MAX_LIMIT_NUM;
|
||||
|
||||
/**
|
||||
* 默认备份文件个数最大限值
|
||||
*/
|
||||
private static Integer DEFAULT_MAX_LIMITNUM = 20;
|
||||
|
||||
@Override
|
||||
public Integer getMaxLimitNum() {
|
||||
if (MAX_LIMIT_NUM == null) {
|
||||
MAX_LIMIT_NUM = DEFAULT_MAX_LIMITNUM;
|
||||
}
|
||||
return MAX_LIMIT_NUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxLimitNum(Integer limitNum) {
|
||||
if (limitNum == null) {
|
||||
throw new RuntimeException("database_maxLimitNum_setting_null");
|
||||
}
|
||||
MAX_LIMIT_NUM = limitNum;
|
||||
|
||||
lock.writeLock().lock();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
File file = new File(BACKUP_RECORD_XML_PATH);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
|
||||
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
|
||||
|
||||
Element maxLimitNumE = (Element) document.selectSingleNode("/DbBackupRecordList/maxLimitNum");
|
||||
if (maxLimitNumE == null) {
|
||||
maxLimitNumE = document.getRootElement().addElement("maxLimitNum");
|
||||
}
|
||||
maxLimitNumE.setText(String.valueOf(MAX_LIMIT_NUM));
|
||||
|
||||
HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH);
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
IOUtil.closeQuietly(fis);
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<DBBackupRecord> findAll() {
|
||||
return BKRECORD_CACHE.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBBackupRecord findByUuid(Serializable uuid) {
|
||||
if (uuid == null) {
|
||||
throw new RuntimeException("database_backuprecord_uuid_null");
|
||||
// throw new FastFailException(MessageFormat.format("database_backuprecord_uuid_null"));
|
||||
}
|
||||
return BKRECORD_CACHE.get(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(DBBackupRecord record) {
|
||||
if (record == null) {
|
||||
throw new RuntimeException("database_backuprecord_add_null");
|
||||
// throw new FastFailException(MessageFormat.format("database_backuprecord_add_null"));
|
||||
}
|
||||
|
||||
lock.writeLock().lock();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
|
||||
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
|
||||
Element root = document.getRootElement();
|
||||
Element recordNode = root.addElement("DbBackupRecord");
|
||||
String uuid = record.getUuid();
|
||||
recordNode.addAttribute("uuid", uuid != null ? uuid : "");
|
||||
|
||||
Element nameNode = recordNode.addElement("name");
|
||||
nameNode.setText(record.getName() != null ? record.getName() : "");
|
||||
|
||||
Element filePathNode = recordNode.addElement("filePath");
|
||||
filePathNode.setText(record.getFilePath() != null ? record.getFilePath() : "");
|
||||
|
||||
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
|
||||
Element timePathNode = recordNode.addElement("backupTime");
|
||||
timePathNode.setText(record.getBackupTime() != null ? sdf.format(record.getBackupTime()) : "");
|
||||
|
||||
Element fileSizeNode = recordNode.addElement("fileSize");
|
||||
fileSizeNode.setText(String.valueOf(record.getFileSize()));
|
||||
|
||||
Element descriptionNode = recordNode.addElement("description");
|
||||
String description = record.getDescription();
|
||||
descriptionNode.setText(description == null ? "" : description);
|
||||
|
||||
// 超过最大限制值,去除旧备份
|
||||
if (BKRECORD_CACHE.size() >= getMaxLimitNum()) {
|
||||
HandleXML.deleteFirstNode("/DbBackupRecordList/DbBackupRecord", document);
|
||||
}
|
||||
|
||||
HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH);
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
IOUtil.closeQuietly(fis);
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
putBackupRecordCache(record);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Serializable uuid) {
|
||||
if (uuid == null) {
|
||||
throw new RuntimeException("database_backuprecord_delete_null");
|
||||
// throw new FastFailException(MessageFormat.format("database_backuprecord_delete_null"));
|
||||
}
|
||||
|
||||
DBBackupRecord record = BKRECORD_CACHE.get(uuid);
|
||||
if (record == null) {
|
||||
throw new RuntimeException("database_backuprecord_delete_null");
|
||||
// throw new FastFailException(MessageFormat.format("database_backuprecord_delete_null"));
|
||||
}
|
||||
|
||||
// 删除备份文件
|
||||
File file = new File(record.getFilePath());
|
||||
if (file.exists()) {
|
||||
if (file.delete()) {
|
||||
String msg = MessageFormat.format("database_backuprecord_delete_file_failed", file.getAbsoluteFile());
|
||||
throw new RuntimeException(msg);
|
||||
// throw new FastFailException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
lock.writeLock().lock();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
|
||||
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
|
||||
String xpathExpression = "/DbBackupRecordList/DbBackupRecord[@uuid=\"" + uuid + "\"]";
|
||||
Element ele = (Element) document.selectSingleNode(xpathExpression);
|
||||
if (ele != null) {
|
||||
ele.getParent().remove(ele);
|
||||
}
|
||||
|
||||
HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH);
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
IOUtil.closeQuietly(fis);
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
removeBackupRecordCache(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteByIds(Serializable[] ids) {
|
||||
int count = 0;
|
||||
for (Serializable id : ids) {
|
||||
delete(id);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 存入缓存 </p>
|
||||
* <p>Create Time: 2013-2-5 </p>
|
||||
* @author weiminghua
|
||||
* @param record 备份记录
|
||||
*/
|
||||
private void putBackupRecordCache(DBBackupRecord record) {
|
||||
BKRECORD_CACHE.put(record.getUuid(), record);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 从缓存中删除数据 </p>
|
||||
* <p>Create Time: 2013-2-5 </p>
|
||||
* @author weiminghua
|
||||
* @param uuid 备份记录ID
|
||||
*/
|
||||
private void removeBackupRecordCache(Serializable uuid) {
|
||||
BKRECORD_CACHE.remove(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
|
||||
lock.readLock().lock();
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
File file = new File(BACKUP_RECORD_XML_PATH);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
|
||||
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
|
||||
|
||||
Element maxLimitNumE = (Element) document.selectSingleNode("/DbBackupRecordList/maxLimitNum");
|
||||
if (maxLimitNumE != null) {
|
||||
MAX_LIMIT_NUM = Integer.parseInt(maxLimitNumE.getText());
|
||||
}
|
||||
|
||||
// 读取已有备份信息
|
||||
List<?> list = document.selectNodes("/DbBackupRecordList/DbBackupRecord");
|
||||
Iterator<?> iter = list.iterator();
|
||||
|
||||
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
|
||||
while (iter.hasNext()) {
|
||||
Element e = (Element) iter.next();
|
||||
DBBackupRecord record = new DBBackupRecord();
|
||||
record.setUuid(e.attribute("uuid").getValue());
|
||||
|
||||
Element nameE = e.element("name");
|
||||
if (nameE != null) {
|
||||
record.setName(nameE.getText());
|
||||
}
|
||||
|
||||
Element backupTimeE = e.element("backupTime");
|
||||
if (backupTimeE != null) {
|
||||
record.setBackupTime(sdf.parse(backupTimeE.getText()));
|
||||
}
|
||||
|
||||
Element filePathE = e.element("filePath");
|
||||
if (filePathE != null) {
|
||||
record.setFilePath(filePathE.getText());
|
||||
}
|
||||
|
||||
Element fileSizeE = e.element("fileSize");
|
||||
if (fileSizeE != null) {
|
||||
record.setFileSize(Long.valueOf(fileSizeE.getText()));
|
||||
}
|
||||
|
||||
Element descriptionE = e.element("description");
|
||||
if (descriptionE != null) {
|
||||
record.setDescription(descriptionE.getText());
|
||||
}
|
||||
|
||||
putBackupRecordCache(record); // 加入缓存
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("error", e);
|
||||
} finally {
|
||||
IOUtil.closeQuietly(fis);
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
44
comm/DB/src/db/support/DefaultOpertProcessListener.java
Executable file
44
comm/DB/src/db/support/DefaultOpertProcessListener.java
Executable file
@@ -0,0 +1,44 @@
|
||||
package db.support;
|
||||
|
||||
import db.OpertProcessListener;
|
||||
|
||||
public class DefaultOpertProcessListener implements OpertProcessListener {
|
||||
|
||||
/**
|
||||
* 输出信息监听器
|
||||
*/
|
||||
private MessageOutputListener outputListener = new MessageOutputListener();
|
||||
|
||||
/**
|
||||
* 是否结束
|
||||
*/
|
||||
private boolean isFinish = false;
|
||||
|
||||
/**
|
||||
* @return 输出信息监听器
|
||||
*/
|
||||
@Override
|
||||
public MessageOutputListener getOutputListener() {
|
||||
return outputListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterrupt() {
|
||||
onExit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExit() {
|
||||
isFinish = true;
|
||||
outputListener.onExit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否中止
|
||||
*/
|
||||
@Override
|
||||
public boolean isFinish() {
|
||||
return isFinish;
|
||||
}
|
||||
|
||||
}
|
||||
63
comm/DB/src/db/support/MessageOutputListener.java
Executable file
63
comm/DB/src/db/support/MessageOutputListener.java
Executable file
@@ -0,0 +1,63 @@
|
||||
package db.support;
|
||||
|
||||
|
||||
public class MessageOutputListener {
|
||||
|
||||
/**
|
||||
* 输出信息缓存
|
||||
*/
|
||||
private StringBuffer sb = new StringBuffer();
|
||||
|
||||
/**
|
||||
* 是否结束
|
||||
*/
|
||||
private boolean isFinish;
|
||||
|
||||
// @Override
|
||||
public void onOutput(String line) {
|
||||
if (sb.length() != 0) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append(line);
|
||||
}
|
||||
|
||||
public void onExit() {
|
||||
this.isFinish = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Description: 是否已经结束 </p>
|
||||
* <p>Create Time: 2012-12-24 </p>
|
||||
* @author wangyongdi
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean isFinish() {
|
||||
return isFinish;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Description: 获取输出信息,以增量的形式输出。当之前的对象已经取出之后,就不再保留。若执行已经结束且所有信息已经取走,返回null;若没有信息,返回空串;</p>
|
||||
* <p>Create Time: 2012-12-24 </p>
|
||||
* @author wangyongdi
|
||||
* @return 输出的信息
|
||||
*/
|
||||
public String getOutputString() {
|
||||
if (isFinish && sb.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
String str;
|
||||
if (sb.length() == 0) {
|
||||
str = "";
|
||||
}
|
||||
else {
|
||||
str = sb.toString();
|
||||
sb = new StringBuffer();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
368
comm/DB/src/db/util/BackupUtil.java
Executable file
368
comm/DB/src/db/util/BackupUtil.java
Executable file
@@ -0,0 +1,368 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import db.Constants;
|
||||
import db.PropertiesUtilDB;
|
||||
import db.util.jdbc.DBTools;
|
||||
import kernel.util.DateUtils;
|
||||
import kernel.util.Endecrypt;
|
||||
import kernel.util.StringUtils;
|
||||
import kernel.util.ThreadUtils;
|
||||
import project.log.SysLog;
|
||||
import project.log.SysLogService;
|
||||
import project.syspara.SysparaService;
|
||||
|
||||
public class BackupUtil {
|
||||
private static transient Logger log = LoggerFactory.getLogger(BackupUtil.class);
|
||||
private static String KEY = "Roj6#@08SDF87323FG00%jjsd";
|
||||
/**
|
||||
* 局部备份
|
||||
*/
|
||||
public static String TYPE_PART = "part";
|
||||
/**
|
||||
* 全局备份
|
||||
*/
|
||||
public static String TYPE_ALL = "all";
|
||||
/**
|
||||
* 局部+全局备份
|
||||
*/
|
||||
public static String TYPE_BOTH = "both";
|
||||
private static Endecrypt endecrypt = new Endecrypt();
|
||||
|
||||
public static void main(String[] args) {
|
||||
// backup(null);
|
||||
// backupPart(null);
|
||||
}
|
||||
|
||||
public static String executeLinuxCmd(String cmd) {
|
||||
// System.out.println("got cmd job : " + cmd);
|
||||
Runtime run = Runtime.getRuntime();
|
||||
try {
|
||||
Process process = null;
|
||||
if(cmd.indexOf(">")!=-1||cmd.indexOf("|")!=-1||cmd.indexOf("\\")!=-1) {
|
||||
String[] command = { "/bin/sh", "-c", cmd};
|
||||
process = run.exec(command);
|
||||
}else {
|
||||
process = run.exec(cmd);
|
||||
}
|
||||
// Process process = run.exec(cmd);
|
||||
InputStream in = process.getInputStream();
|
||||
// BufferedReader bs = new BufferedReader(new InputStreamReader(in));
|
||||
// System.out.println("[check] now size \n"+bs.readLine());
|
||||
StringBuffer out = new StringBuffer();
|
||||
byte[] b = new byte[8192];
|
||||
for (int n; (n = in.read(b)) != -1;) {
|
||||
out.append(new String(b, 0, n));
|
||||
}
|
||||
// System.out.println("job result [" + out.toString() + "]");
|
||||
in.close();
|
||||
// process.waitFor();
|
||||
process.destroy();
|
||||
return out.toString();
|
||||
} catch (IOException e) {
|
||||
log.error("exec cmd fail e:",e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void backup(SysLogService sysLogService, SysparaService sysparaService) {
|
||||
try {
|
||||
log.info("进入全局备份 backup...");
|
||||
boolean backup_all_button = sysparaService.find("backup_all_button").getBoolean();
|
||||
if (!backup_all_button) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* 保留n天的备份,之前清除
|
||||
*/
|
||||
String backup_stay_days = sysparaService.find("backup_stay_days").getValue();
|
||||
String backupType = TYPE_ALL;
|
||||
log.info("开始备份...");
|
||||
|
||||
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
|
||||
String backupName = PropertiesUtilDB.getProperty("db.database.name") + "_" + sdf.format(new Date());
|
||||
|
||||
executeLinuxCmd("mkdir " + PropertiesUtilDB.getProperty("db.backup.path"));
|
||||
// 开始备份sql
|
||||
String backupDB = backupDB(backupName);
|
||||
|
||||
String backResult = executeLinuxCmd(backupDB);
|
||||
log.info(backResult);
|
||||
// 开始压缩zip
|
||||
String zip = zip(backupName);
|
||||
log.info(zip);
|
||||
String zipResult = executeLinuxCmd(zip);
|
||||
log.info(zipResult);
|
||||
// 保留n天,删除之前的zip
|
||||
|
||||
String clearBackup = clearBackup(backup_stay_days, backupType);
|
||||
log.info(clearBackup);
|
||||
String clearBackupResult = executeLinuxCmd(clearBackup);
|
||||
log.info(clearBackupResult);
|
||||
ThreadUtils.sleep(2000);// 等待备份完成
|
||||
|
||||
handleSftp(sysparaService, PropertiesUtilDB.getProperty("db.backup.path") + "/" + backupName + ".zip",
|
||||
backupType, backup_stay_days);
|
||||
log.info("备份完成...");
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
log.error(DateUtils.format(new Date(), DateUtils.DF_yyyyMMddHHmmss) + " backup fail e:", e);
|
||||
SysLog entity = new SysLog();
|
||||
entity.setLevel(SysLog.level_error);
|
||||
entity.setCreateTime(new Date());
|
||||
entity.setLog("数据库备份失败 e:" + e);
|
||||
sysLogService.saveAsyn(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份文件发送到配置的服务
|
||||
*
|
||||
* @param filePath 指定文件目录
|
||||
* @param sysparaService
|
||||
*/
|
||||
public static void handleSftp(SysparaService sysparaService, String filePath, String backupType,
|
||||
String backupStayDays) throws Exception {
|
||||
// String backup_server_param="[{\"ip\":\"127.0.0.1\",\"port\":\"22\",\"username\":\"root\",\"password\":\"g5xkwp8ET2WCTbtb5aAxeq2%2FQsWR3j35MbsW2bpXDhp0NsW%2BNNfzSA%3D%3D\",\"path\":\"/backup\",\"type\":\"part\"},{\"ip\":\"127.0.0.1\",\"port\":\"22\",\"username\":\"root\",\"password\":\"g5xkwp8ET2WCTbtb5aAxeq2%2FQsWR3j35MbsW2bpXDhp0NsW%2BNNfzSA%3D%3D\",\"path\":\"/backup\",\"type\":\"part\"}]";
|
||||
String backup_server_param = sysparaService.find("backup_server_param").getValue();
|
||||
if (StringUtils.isEmptyString(backup_server_param)) {
|
||||
return;
|
||||
}
|
||||
JSONArray jsonArray = JSON.parseArray(backup_server_param);
|
||||
Iterator<Object> iterator = jsonArray.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
JSONObject next = (JSONObject) iterator.next();
|
||||
|
||||
String type = next.getString("type");
|
||||
if (!type.equals(TYPE_BOTH) && !backupType.equals(type)) {
|
||||
continue;
|
||||
}
|
||||
String sftpIp = next.getString("ip");
|
||||
int sftpPort = next.getInteger("port");
|
||||
String sftpUsername = next.getString("username");
|
||||
String sftpPassword = endecrypt.get3DESDecrypt(next.getString("password"), KEY);
|
||||
String sftpBackupPath = next.getString("path");
|
||||
try {
|
||||
sftp(filePath, sftpIp, sftpPort, sftpUsername, sftpPassword, sftpBackupPath, backupStayDays, backupType);
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
log.error("ip:"+sftpIp+" sftp fail. e:",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 备份文件发送到指定服务
|
||||
*
|
||||
* @param filePath
|
||||
* @param sftpIp
|
||||
* @param sftpPort
|
||||
* @param sftpUsername
|
||||
* @param sftpPassword
|
||||
* @param sftpBackupPath
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void sftp(String filePath, String sftpIp, int sftpPort, String sftpUsername, String sftpPassword,
|
||||
String sftpBackupPath, String backupStayDays, String backupType) throws Exception {
|
||||
SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
|
||||
//1.传输中途中断,2.未连接上
|
||||
if(TYPE_ALL.equals(backupType)) {//全局备份
|
||||
int times = 0;//次数
|
||||
long start = System.currentTimeMillis();
|
||||
long end = System.currentTimeMillis();
|
||||
long limit = 1000 * 60 * 5;
|
||||
while(true) {
|
||||
try {
|
||||
sftp.login(SFTPUtil.SFTP);
|
||||
sftp.upload(sftpBackupPath, filePath);
|
||||
break;
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
times++;
|
||||
end = System.currentTimeMillis();
|
||||
if(times>5||(end-start)>limit) {//尝试5分钟,或尝试次数大于五
|
||||
log.error("尝试时间大于五分钟,或尝试次数大于五,无法传输成功",times);
|
||||
throw new RuntimeException(e);
|
||||
}else {
|
||||
log.error("全局备份传输失败,尝试第{}次。。。",times);
|
||||
}
|
||||
}finally {
|
||||
sftp.logout();
|
||||
}
|
||||
|
||||
}
|
||||
}else {
|
||||
sftp.login(SFTPUtil.SFTP);
|
||||
sftp.upload(sftpBackupPath, filePath);
|
||||
sftp.logout();
|
||||
}
|
||||
|
||||
// 保留n天删除之前的zip
|
||||
String clearBackup = clearBackup(backupStayDays, backupType);
|
||||
log.info("sftp:" + clearBackup);
|
||||
String clearBackupResult = SFTPUtil.execCmd(sftpIp, sftpUsername,sftpPort, sftpPassword, clearBackup);
|
||||
log.info(clearBackupResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 局部备份
|
||||
*
|
||||
* @param sysLogService
|
||||
*/
|
||||
public static void backupPart(SysLogService sysLogService, SysparaService sysparaService) {
|
||||
try {
|
||||
// log.info("进入局部备份 backupPart...");
|
||||
boolean backup_part_button = sysparaService.find("backup_part_button").getBoolean();
|
||||
if (!backup_part_button) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* 保留n天的备份,之前清除
|
||||
*/
|
||||
String backup_stay_days = sysparaService.find("backup_stay_days").getValue();
|
||||
String backup_part_notable = sysparaService.find("backup_part_notable").getValue();
|
||||
String backupType = TYPE_PART;
|
||||
// log.info("开始局部备份...");
|
||||
|
||||
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
|
||||
String backupName = PropertiesUtilDB.getProperty("db.database.name") + "_part_" + sdf.format(new Date());
|
||||
|
||||
executeLinuxCmd("mkdir " + PropertiesUtilDB.getProperty("db.backup.path"));
|
||||
// 开始备份sql
|
||||
String backupDB = backupPartDB(backupName, backup_part_notable);
|
||||
String backResult = executeLinuxCmd(backupDB);
|
||||
// log.info(backResult);
|
||||
// 开始压缩zip
|
||||
String zip = zip(backupName);
|
||||
// log.info(zip);
|
||||
String zipResult = executeLinuxCmd(zip);
|
||||
// log.info(zipResult);
|
||||
// 保留n天删除之前的zip
|
||||
String clearBackup = clearBackup(backup_stay_days, backupType);
|
||||
// log.info(clearBackup);
|
||||
String clearBackupResult = executeLinuxCmd(clearBackup);
|
||||
// log.info(clearBackupResult);
|
||||
ThreadUtils.sleep(2000);// 等待备份完成
|
||||
|
||||
handleSftp(sysparaService, PropertiesUtilDB.getProperty("db.backup.path") + "/" + backupName + ".zip",
|
||||
backupType, backup_stay_days);
|
||||
|
||||
log.info("备份完成...");
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
log.error(DateUtils.format(new Date(), DateUtils.DF_yyyyMMddHHmmss) + " backup fail e:", e);
|
||||
SysLog entity = new SysLog();
|
||||
entity.setLevel(SysLog.level_error);
|
||||
entity.setCreateTime(new Date());
|
||||
entity.setLog("数据库备份失败 e:" + e);
|
||||
sysLogService.saveAsyn(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public static String backupDB(String backupName) {
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
|
||||
|
||||
cmdBuf.append(" -h ").append(PropertiesUtilDB.getProperty("db.ip"));
|
||||
cmdBuf.append(" -P ").append(PropertiesUtilDB.getProperty("db.port"));
|
||||
cmdBuf.append(" -u").append(PropertiesUtilDB.getProperty("db.username"));
|
||||
cmdBuf.append(" -p")
|
||||
.append("'" + endecrypt.get3DESDecrypt(PropertiesUtilDB.getProperty("db.password"), KEY) + "'");
|
||||
cmdBuf.append(" ").append(PropertiesUtilDB.getProperty("db.database.name"));
|
||||
cmdBuf.append(" > ")//
|
||||
// .append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
|
||||
.append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName).append(".sql");
|
||||
return cmdBuf.toString();
|
||||
}
|
||||
|
||||
public static String backupPartDB(String backupName, String noTable) {
|
||||
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
|
||||
|
||||
cmdBuf.append(" -h ").append(PropertiesUtilDB.getProperty("db.ip"));
|
||||
cmdBuf.append(" -P ").append(PropertiesUtilDB.getProperty("db.port"));
|
||||
cmdBuf.append(" -u").append(PropertiesUtilDB.getProperty("db.username"));
|
||||
cmdBuf.append(" -p")
|
||||
.append("'" + endecrypt.get3DESDecrypt(PropertiesUtilDB.getProperty("db.password"), KEY) + "'");
|
||||
cmdBuf.append(" --skip-opt");// 运行中的数据库谨慎备份,忽略部分表结构参数
|
||||
cmdBuf.append(" ").append(PropertiesUtilDB.getProperty("db.database.name"));
|
||||
|
||||
// String notable = PropertiesUtilDB.getProperty("backup.part.notable");
|
||||
if (StringUtils.isNotEmpty(noTable)) {
|
||||
String baseCmd = "--ignore-table=" + PropertiesUtilDB.getProperty("db.database.name") + ".";
|
||||
for (String t : noTable.split(",")) {
|
||||
cmdBuf.append(" ").append(baseCmd + t);
|
||||
}
|
||||
}
|
||||
|
||||
cmdBuf.append(" > ")//
|
||||
// .append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
|
||||
.append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName).append(".sql");
|
||||
return cmdBuf.toString();
|
||||
}
|
||||
|
||||
public static String zip(String backupName) {
|
||||
// String zip="zip -m /home/demo7.zip /home/demo7.sql";
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append("zip"); // 客户端命令
|
||||
|
||||
cmdBuf.append(" -m ").append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName)
|
||||
.append(".zip");
|
||||
cmdBuf.append(" ").append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName)
|
||||
.append(".sql");
|
||||
return cmdBuf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除超时备份
|
||||
*
|
||||
* @param days 备份保留时间
|
||||
* @return
|
||||
*/
|
||||
public static String clearBackup(String days, String backupType) {
|
||||
// find /backup/test -mtime +2 -type f -name *.txt -exec rm {} \;
|
||||
// StringBuffer cmdBuf = new StringBuffer("find /backup -mmin +120 -type f -name *.zip -exec rm {} \\;");
|
||||
StringBuffer cmdBuf = new StringBuffer();
|
||||
cmdBuf.append(" find ").append(PropertiesUtilDB.getProperty("db.backup.path"));
|
||||
cmdBuf.append(" -mtime ").append("+" + days);
|
||||
String dbName = PropertiesUtilDB.getProperty("db.database.name") + "_part_";
|
||||
if (backupType.equals(TYPE_ALL)) {// 优先处理part,全局的匹配了再处理
|
||||
dbName = PropertiesUtilDB.getProperty("db.database.name") + "_";
|
||||
}
|
||||
cmdBuf.append(" -type f -name '" + dbName + "*.zip' -exec rm {} \\; ");
|
||||
|
||||
return cmdBuf.toString();
|
||||
}
|
||||
|
||||
// public static void sftpPart(String filePath) throws Exception {
|
||||
// String sftpBackupPath = PropertiesUtilDB.getProperty("sftp.backup.path");
|
||||
// String sftpUsername = PropertiesUtilDB.getProperty("sftp.username");
|
||||
// String sftpPassword = endecrypt.get3DESDecrypt(PropertiesUtilDB.getProperty("sftp.password"), KEY);
|
||||
// String sftpIp = PropertiesUtilDB.getProperty("sftp.ip");
|
||||
// int sftpPort = Integer.valueOf(PropertiesUtilDB.getProperty("sftp.port"));
|
||||
// SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
|
||||
// sftp.login(SFTPUtil.SFTP);
|
||||
// sftp.upload(sftpBackupPath, filePath);
|
||||
// sftp.logout();
|
||||
//
|
||||
// // 保留n天删除之前的zip
|
||||
// String clearBackup = clearBackup(2,);
|
||||
// log.info("sftp:" + clearBackup);
|
||||
// String clearBackupResult = SFTPUtil.execCmd(sftpIp, sftpUsername, sftpPassword, clearBackup);
|
||||
// log.info(clearBackupResult);
|
||||
// }
|
||||
}
|
||||
52
comm/DB/src/db/util/CMDUtil.java
Executable file
52
comm/DB/src/db/util/CMDUtil.java
Executable file
@@ -0,0 +1,52 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CMDUtil {
|
||||
|
||||
public static String runCMD(String cmd) throws IOException {
|
||||
// ProcessBuilder是一个用于创建操作系统进程的类,它的start()方法用于启动一个进行
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
|
||||
// 启动进程
|
||||
Process process = processBuilder.start();
|
||||
// 解析输出
|
||||
String result = convertStreamToStr(process.getInputStream());
|
||||
// System.out.println(result);
|
||||
return result;
|
||||
}
|
||||
public static String runCMD(List<String> commandList) throws IOException {
|
||||
// 创建命令集合
|
||||
// ProcessBuilder是一个用于创建操作系统进程的类,它的start()方法用于启动一个进行
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(commandList);
|
||||
// 启动进程
|
||||
Process process = processBuilder.start();
|
||||
// 解析输出
|
||||
String result = convertStreamToStr(process.getInputStream());
|
||||
// System.out.println(result);
|
||||
return result;
|
||||
}
|
||||
public static String convertStreamToStr(InputStream is) throws IOException {
|
||||
if (is != null) {
|
||||
Writer writer = new StringWriter();
|
||||
char[] buffer = new char[1024];
|
||||
try {
|
||||
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
||||
int n;
|
||||
while ((n = reader.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, n);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
return writer.toString();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
52
comm/DB/src/db/util/ConfigUtils.java
Executable file
52
comm/DB/src/db/util/ConfigUtils.java
Executable file
@@ -0,0 +1,52 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import db.SupportDBTypeEnum;
|
||||
|
||||
|
||||
public class ConfigUtils {
|
||||
|
||||
/**
|
||||
* 当前数据库类型
|
||||
*/
|
||||
private static SupportDBTypeEnum CURRENT_DB_TYPE = null;
|
||||
|
||||
/**
|
||||
* 当前数据库类型(默认mysql)
|
||||
*
|
||||
* @return The current database type
|
||||
*/
|
||||
public static SupportDBTypeEnum getCurrentDBType() {
|
||||
if (CURRENT_DB_TYPE == null) {
|
||||
String dbName = System.getProperty("components.ha.database.DBType", //
|
||||
SupportDBTypeEnum.mysql.name()); // 默认mysql
|
||||
CURRENT_DB_TYPE = SupportDBTypeEnum.getEnum(dbName);
|
||||
}
|
||||
return CURRENT_DB_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库备份信息XML路径(文件数据库)
|
||||
* @return 文件数据库路径
|
||||
*/
|
||||
public static String getBackupRecordXMLPath() {
|
||||
String databasePath = PathUtil.getDatabasePath();
|
||||
String backupRecordXML = System.getProperty("components.ha.database.backupRecordXML", "");
|
||||
if ("".equals(backupRecordXML)) {
|
||||
backupRecordXML = databasePath + File.separator + "backupRecords.xml";
|
||||
}
|
||||
|
||||
return backupRecordXML;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库客户端程序安装bin目录(支持空格)
|
||||
*
|
||||
* @return The installation directory
|
||||
*/
|
||||
public static String getDBInstalledPath() {
|
||||
return System.getProperty("components.ha.database.installedPath", null);
|
||||
}
|
||||
|
||||
}
|
||||
150
comm/DB/src/db/util/FileUtil.java
Executable file
150
comm/DB/src/db/util/FileUtil.java
Executable file
@@ -0,0 +1,150 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
/**
|
||||
* Member Description
|
||||
*/
|
||||
private static Logger logger = LogManager.getLogger(FileUtil.class);
|
||||
|
||||
/** .
|
||||
* 文件字符集
|
||||
*/
|
||||
private static final String CHARSET_NAME = "UTF-8";
|
||||
|
||||
/**
|
||||
* <p>Description: 将内容写入指定文件 </p>
|
||||
* <p>Create Time: </p>
|
||||
* @param fileContent 内容
|
||||
* @param filePath 文件路径
|
||||
*/
|
||||
public static void string2File(String fileContent, String filePath) {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
File outFile = new File(filePath);
|
||||
if (!outFile.exists()) {
|
||||
outFile.createNewFile();
|
||||
}
|
||||
fos = new FileOutputStream(outFile);
|
||||
fos.write(fileContent.getBytes(CHARSET_NAME), 0, fileContent.getBytes(CHARSET_NAME).length);
|
||||
} catch (Exception e) {
|
||||
logger.error("The string2File[" + filePath + "] ERROR", e);
|
||||
} finally {
|
||||
IOUtil.closeQuietly(fos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取文件
|
||||
* @param ins 文件流
|
||||
* @return 文件内容
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public static String readStringAndClose(InputStream ins) throws Exception {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(ins, "UTF-8"));
|
||||
String lineStr = null;
|
||||
while ((lineStr = br.readLine()) != null) {
|
||||
buf.append(lineStr).append("\n");
|
||||
}
|
||||
if (br != null) {
|
||||
br.close();
|
||||
}
|
||||
if (ins != null) {
|
||||
ins.close();
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除目录下的文件
|
||||
* @param path 目录名
|
||||
* @param isDeleteSelf 是否删除目录自身
|
||||
*/
|
||||
public static void deleteDir(String path, boolean isDeleteSelf) {
|
||||
File dir = new File(path);
|
||||
// 检查参数
|
||||
if (dir == null || !dir.exists() || !dir.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.isFile()) {
|
||||
// 删除所有文件
|
||||
file.delete();
|
||||
}
|
||||
else if (file.isDirectory()) {
|
||||
// 递规的方式删除文件夹
|
||||
deleteDir(file.getPath(), true);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除目录本身
|
||||
if (isDeleteSelf) {
|
||||
dir.delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件大小
|
||||
* @param filePath 文件路径
|
||||
* @return 文件大小
|
||||
* @throws FileNotFoundException 文件不存在
|
||||
*/
|
||||
public static long getFileSize(String filePath) throws FileNotFoundException {
|
||||
File file = new File(filePath);
|
||||
long size = 0;
|
||||
if (file.exists()) {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
size = fis.available();
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
IOUtil.closeQuietly(fis);
|
||||
}
|
||||
} else {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换文件大小格式
|
||||
* @param fileSize 文件大小
|
||||
* @param df 格式
|
||||
* @return 文件大小格式
|
||||
*/
|
||||
public static String formetFileSize(long fileSize, DecimalFormat df) {
|
||||
if (df == null) {
|
||||
df = new DecimalFormat("#.000");
|
||||
}
|
||||
String result = "";
|
||||
if (fileSize < 1024) {
|
||||
result = df.format((double) fileSize) + "B";
|
||||
}
|
||||
else if (fileSize < 1048576) { // 1024*1024
|
||||
result = df.format((double) fileSize / 1024) + "K";
|
||||
}
|
||||
else if (fileSize < 1073741824) { // 1024*1024*1024
|
||||
result = df.format((double) fileSize / 1048576) + "M";
|
||||
}
|
||||
else { // 1024*1024*1024*1024
|
||||
result = df.format((double) fileSize / 1073741824) + "G";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
92
comm/DB/src/db/util/HandleXML.java
Executable file
92
comm/DB/src/db/util/HandleXML.java
Executable file
@@ -0,0 +1,92 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
|
||||
public class HandleXML {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
private static Logger logger = LogManager.getLogger(HandleXML.class);
|
||||
|
||||
/**
|
||||
* <p>Description: XML Document 写入文件 </p>
|
||||
* <p>Create Time: </p>
|
||||
* @param document XML Document
|
||||
* @param filePath 文件路径
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
public static void writeToXML(Document document, String filePath) throws Exception {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||
format.setEncoding("UTF-8"); // 设置XML文件的编码格式
|
||||
os = new FileOutputStream(filePath);
|
||||
XMLWriter xmlout = new XMLWriter(os, format);
|
||||
xmlout.write(document);
|
||||
xmlout.close();
|
||||
} catch (Exception e) {
|
||||
logger.error("write to xml [" + filePath + "] error", e);
|
||||
throw new Exception(e);
|
||||
} finally {
|
||||
IOUtil.closeQuietly(os);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: Get XML Document </p>
|
||||
* <p>Create Time: 2013-2-6 </p>
|
||||
* @param fis 文件输入流
|
||||
* @param rootName 根节点名称
|
||||
* @return XML Document
|
||||
*/
|
||||
public static Document getDocument(FileInputStream fis, String rootName) {
|
||||
Document document = null;
|
||||
try {
|
||||
SAXReader saxReader = new SAXReader();
|
||||
document = saxReader.read(fis);
|
||||
} catch (DocumentException e) {
|
||||
document = DocumentHelper.createDocument();
|
||||
document.addElement(rootName); // root
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 删除XML Document查找到的第一条记录 </p>
|
||||
* <p>Create Time: 2013-2-6 </p>
|
||||
* @author weiminghua
|
||||
* @param xpathExpression 匹配正则
|
||||
* @param document XML Document
|
||||
* @return 删除结果
|
||||
*/
|
||||
public static boolean deleteFirstNode(String xpathExpression, Document document) {
|
||||
List<?> list = document.selectNodes(xpathExpression);
|
||||
if (list.size() > 0) {
|
||||
Element e = (Element) list.get(0);
|
||||
return e.getParent().remove(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
40
comm/DB/src/db/util/IOUtil.java
Executable file
40
comm/DB/src/db/util/IOUtil.java
Executable file
@@ -0,0 +1,40 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class IOUtil {
|
||||
|
||||
/**
|
||||
* <p>Description: 关闭输入流 </p>
|
||||
* @param is inputStream
|
||||
*/
|
||||
public static void closeQuietly(InputStream is) {
|
||||
if (is == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
is.close();
|
||||
} catch (Throwable e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 关闭输出流 </p>
|
||||
* @param os outputStream
|
||||
*/
|
||||
public static void closeQuietly(OutputStream os) {
|
||||
if (os == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
os.close();
|
||||
} catch (Throwable e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
96
comm/DB/src/db/util/PathUtil.java
Executable file
96
comm/DB/src/db/util/PathUtil.java
Executable file
@@ -0,0 +1,96 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import db.PropertiesUtilDB;
|
||||
|
||||
public class PathUtil {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
private static Logger logger = LogManager.getLogger(PathUtil.class);
|
||||
|
||||
/**
|
||||
* database组件操作路径
|
||||
*/
|
||||
private static String DATABASE_PATH;
|
||||
|
||||
/**
|
||||
* 数据库备份文件存储路径
|
||||
*/
|
||||
private static String DB_BACKUP_PATH;
|
||||
|
||||
/**
|
||||
* 数据库备份的工具路径
|
||||
*/
|
||||
private static String DB_TOOLS_PATH;
|
||||
|
||||
/**
|
||||
* database组件操作目录下tools路径
|
||||
*
|
||||
* @return Returns the databasePath.
|
||||
*/
|
||||
public static String getDatabasePath() {
|
||||
if (DATABASE_PATH == null) {
|
||||
// DATABASE_PATH = getAppRootPath() + File.separator + "database";
|
||||
// DATABASE_PATH = File.separator + "database";
|
||||
// DATABASE_PATH = "C:\\e";
|
||||
DATABASE_PATH = PropertiesUtilDB.getProperty("db.backup.path");
|
||||
|
||||
File f = new File(DATABASE_PATH);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("DatabasePath = " + DATABASE_PATH);
|
||||
}
|
||||
}
|
||||
return DATABASE_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库备份文件存储路径
|
||||
*
|
||||
* @return Returns the dbBackupPath.
|
||||
*/
|
||||
public static String getDbBackupPath() {
|
||||
if (DB_BACKUP_PATH == null) {
|
||||
DB_BACKUP_PATH = getDatabasePath() + File.separator + "backup";
|
||||
File f = new File(DB_BACKUP_PATH);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Database backupPath = " + DB_BACKUP_PATH);
|
||||
}
|
||||
}
|
||||
return DB_BACKUP_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* database组件操作目录下tools路径
|
||||
*
|
||||
* @return dbToolsPath
|
||||
*/
|
||||
public static String getDbToolsPath() {
|
||||
if (DB_TOOLS_PATH == null) {
|
||||
DB_TOOLS_PATH = getDatabasePath() + File.separator + "tools";
|
||||
File f = new File(DB_TOOLS_PATH);
|
||||
if (!f.exists()) {
|
||||
f.mkdir();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Database toolsPath = " + DB_TOOLS_PATH);
|
||||
}
|
||||
}
|
||||
return DB_TOOLS_PATH;
|
||||
}
|
||||
|
||||
}
|
||||
441
comm/DB/src/db/util/SFTPUtil.java
Executable file
441
comm/DB/src/db/util/SFTPUtil.java
Executable file
@@ -0,0 +1,441 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Properties;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.SftpException;
|
||||
|
||||
public class SFTPUtil {
|
||||
private transient Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private ChannelSftp sftp;
|
||||
private ChannelExec exec;
|
||||
public static final String SFTP = "sftp";
|
||||
public static final String SHELL = "exec";
|
||||
private Session session;
|
||||
/** FTP 登录用户名 */
|
||||
private String username;
|
||||
/** FTP 登录密码 */
|
||||
private String password;
|
||||
/** 私钥 */
|
||||
private String privateKey;
|
||||
/** FTP 服务器地址IP地址 */
|
||||
private String host;
|
||||
/** FTP 端口 */
|
||||
private int port;
|
||||
|
||||
/**
|
||||
* 构造基于密码认证的sftp对象
|
||||
*
|
||||
* @param userName
|
||||
* @param password
|
||||
* @param host
|
||||
* @param port
|
||||
*/
|
||||
public SFTPUtil(String username, String password, String host, int port) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造基于秘钥认证的sftp对象
|
||||
*
|
||||
* @param userName
|
||||
* @param host
|
||||
* @param port
|
||||
* @param privateKey
|
||||
*/
|
||||
public SFTPUtil(String username, String host, int port, String privateKey) {
|
||||
this.username = username;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public SFTPUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接sftp服务器
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void login(String type) {
|
||||
try {
|
||||
JSch jsch = new JSch();
|
||||
if (privateKey != null) {
|
||||
jsch.addIdentity(privateKey);// 设置私钥
|
||||
// log.info("sftp connect,path of private key file:{}" , privateKey);
|
||||
}
|
||||
// log.info("sftp connect by host:{} username:{}",host,username);
|
||||
|
||||
session = jsch.getSession(username, host, port);
|
||||
// log.info("Session is build");
|
||||
if (password != null) {
|
||||
session.setPassword(password);
|
||||
}
|
||||
Properties config = new Properties();
|
||||
config.put("StrictHostKeyChecking", "no");
|
||||
|
||||
session.setConfig(config);
|
||||
session.connect();
|
||||
// log.info("Session is connected");
|
||||
|
||||
Channel channel = session.openChannel(type);
|
||||
channel.connect();
|
||||
if (SFTP.equals(type)) {
|
||||
log.info("sftp channel is connected");
|
||||
sftp = (ChannelSftp) channel;
|
||||
} else if (SHELL.equals(type)) {
|
||||
log.info("shell channel is connected");
|
||||
exec = (ChannelExec) channel;
|
||||
}
|
||||
// Channel channel = session.openChannel("sftp");
|
||||
// log.info(String.format("sftp server host:[%s] port:[%s] is connect successfull", host, port));
|
||||
} catch (JSchException e) {
|
||||
// log.error("Cannot connect to specified sftp server : {}:{} \n Exception message is: {}", new Object[]{host, port, e.getMessage()});
|
||||
log.error("Cannot connect to specified sftp server \n Exception message is: {}",
|
||||
new Object[] { e.getMessage() });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭连接 server
|
||||
*/
|
||||
public void logout() {
|
||||
if (sftp != null) {
|
||||
if (sftp.isConnected()) {
|
||||
sftp.disconnect();
|
||||
log.info("sftp is closed already");
|
||||
}
|
||||
}
|
||||
if (session != null) {
|
||||
if (session.isConnected()) {
|
||||
session.disconnect();
|
||||
log.info("sshSession is closed already");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将输入流的数据上传到sftp作为文件
|
||||
*
|
||||
* @param directory 上传到该目录
|
||||
* @param sftpFileName sftp端文件名
|
||||
* @param in 输入流
|
||||
* @throws SftpException
|
||||
* @throws Exception
|
||||
*/
|
||||
public void upload(String directory, String sftpFileName, InputStream input) throws SftpException {
|
||||
try {
|
||||
sftp.cd(directory);
|
||||
} catch (SftpException e) {
|
||||
log.warn("directory is not exist");
|
||||
sftp.mkdir(directory);
|
||||
sftp.cd(directory);
|
||||
}
|
||||
sftp.put(input, sftpFileName);
|
||||
log.info("file:{} is upload successful", sftpFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传单个文件
|
||||
*
|
||||
* @param directory 上传到sftp目录
|
||||
* @param uploadFile 要上传的文件,包括路径
|
||||
* @throws FileNotFoundException
|
||||
* @throws SftpException
|
||||
* @throws Exception
|
||||
*/
|
||||
public void upload(String directory, String uploadFile) throws FileNotFoundException, SftpException {
|
||||
File file = new File(uploadFile);
|
||||
upload(directory, file.getName(), new FileInputStream(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将byte[]上传到sftp,作为文件。注意:从String生成byte[]是,要指定字符集。
|
||||
*
|
||||
* @param directory 上传到sftp目录
|
||||
* @param sftpFileName 文件在sftp端的命名
|
||||
* @param byteArr 要上传的字节数组
|
||||
* @throws SftpException
|
||||
* @throws Exception
|
||||
*/
|
||||
public void upload(String directory, String sftpFileName, byte[] byteArr) throws SftpException {
|
||||
upload(directory, sftpFileName, new ByteArrayInputStream(byteArr));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串按照指定的字符编码上传到sftp
|
||||
*
|
||||
* @param directory 上传到sftp目录
|
||||
* @param sftpFileName 文件在sftp端的命名
|
||||
* @param dataStr 待上传的数据
|
||||
* @param charsetName sftp上的文件,按该字符编码保存
|
||||
* @throws UnsupportedEncodingException
|
||||
* @throws SftpException
|
||||
* @throws Exception
|
||||
*/
|
||||
public void upload(String directory, String sftpFileName, String dataStr, String charsetName)
|
||||
throws UnsupportedEncodingException, SftpException {
|
||||
upload(directory, sftpFileName, new ByteArrayInputStream(dataStr.getBytes(charsetName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param directory 下载目录
|
||||
* @param downloadFile 下载的文件
|
||||
* @param saveFile 存在本地的路径
|
||||
* @throws SftpException
|
||||
* @throws FileNotFoundException
|
||||
* @throws Exception
|
||||
*/
|
||||
public void download(String directory, String downloadFile, String saveFile)
|
||||
throws SftpException, FileNotFoundException {
|
||||
if (directory != null && !"".equals(directory)) {
|
||||
sftp.cd(directory);
|
||||
}
|
||||
File file = new File(saveFile);
|
||||
sftp.get(downloadFile, new FileOutputStream(file));
|
||||
log.info("file:{} is download successful", downloadFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param directory 下载目录
|
||||
* @param downloadFile 下载的文件名
|
||||
* @return 字节数组
|
||||
* @throws SftpException
|
||||
* @throws IOException
|
||||
* @throws Exception
|
||||
*/
|
||||
public byte[] download(String directory, String downloadFile) throws SftpException, IOException {
|
||||
if (directory != null && !"".equals(directory)) {
|
||||
sftp.cd(directory);
|
||||
}
|
||||
InputStream is = sftp.get(downloadFile);
|
||||
byte[] fileData = IOUtils.toByteArray(is);
|
||||
log.info("file:{} is download successful", downloadFile);
|
||||
return fileData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param directory 要删除文件所在目录
|
||||
* @param deleteFile 要删除的文件
|
||||
* @throws SftpException
|
||||
* @throws Exception
|
||||
*/
|
||||
public void delete(String directory, String deleteFile) throws SftpException {
|
||||
sftp.cd(directory);
|
||||
sftp.rm(deleteFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出目录下的文件
|
||||
*
|
||||
* @param directory 要列出的目录
|
||||
* @param sftp
|
||||
* @return
|
||||
* @throws SftpException
|
||||
*/
|
||||
public Vector<?> listFiles(String directory) throws SftpException {
|
||||
return sftp.ls(directory);
|
||||
}
|
||||
|
||||
public String execCmd(String cmd) {
|
||||
String result = null;
|
||||
try {
|
||||
// 获取输入流和输出流
|
||||
InputStream in = exec.getInputStream();
|
||||
exec.setCommand(cmd);
|
||||
exec.connect();
|
||||
|
||||
byte[] tmp = new byte[1024];
|
||||
while (true) {
|
||||
while (in.available() > 0) {
|
||||
int i = in.read(tmp, 0, 1024);
|
||||
if (i < 0)
|
||||
break;
|
||||
result = new String(tmp, 0, i);
|
||||
}
|
||||
if (exec.isClosed()) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
result = e.toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// log.error(e.getMessage(), e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行远程命令
|
||||
*
|
||||
* @param ip
|
||||
* @param user
|
||||
* @param psw
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String execCmd(String ip, String user, String psw, String cmd) throws Exception {
|
||||
// 连接服务器,采用默认端口
|
||||
JSch jsch = new JSch();
|
||||
Session session = jsch.getSession(user, ip);
|
||||
Channel channel = connect(session, psw, SHELL);
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
ChannelExec channelExec = (ChannelExec) channel;
|
||||
// 获取输入流和输出流
|
||||
InputStream in = channel.getInputStream();
|
||||
channelExec.setCommand(cmd);
|
||||
channelExec.connect();
|
||||
|
||||
byte[] tmp = new byte[1024];
|
||||
while (true) {
|
||||
while (in.available() > 0) {
|
||||
int i = in.read(tmp, 0, 1024);
|
||||
if (i < 0)
|
||||
break;
|
||||
result = new String(tmp, 0, i);
|
||||
}
|
||||
if (channel.isClosed()) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
result = e.toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
session.disconnect();
|
||||
channel.disconnect();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行远程命令
|
||||
*
|
||||
* @param ip
|
||||
* @param user
|
||||
* @param psw
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String execCmd(String ip, String user, int port, String psw, String cmd) throws Exception {
|
||||
// 连接服务器,采用默认端口
|
||||
JSch jsch = new JSch();
|
||||
Session session = jsch.getSession(user, ip, port);
|
||||
Channel channel = connect(session, psw, SHELL);
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
ChannelExec channelExec = (ChannelExec) channel;
|
||||
// 获取输入流和输出流
|
||||
InputStream in = channel.getInputStream();
|
||||
channelExec.setCommand(cmd);
|
||||
channelExec.connect();
|
||||
|
||||
byte[] tmp = new byte[1024];
|
||||
while (true) {
|
||||
while (in.available() > 0) {
|
||||
int i = in.read(tmp, 0, 1024);
|
||||
if (i < 0)
|
||||
break;
|
||||
result = new String(tmp, 0, i);
|
||||
}
|
||||
if (channel.isClosed()) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
result = e.toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
session.disconnect();
|
||||
channel.disconnect();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接服务器
|
||||
*
|
||||
* @param session
|
||||
* @param psw
|
||||
* @param type
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Channel connect(Session session, String psw, String type) throws Exception {
|
||||
// 如果服务器连接不上,则抛出异常
|
||||
if (session == null) {
|
||||
throw new Exception("session is null");
|
||||
}
|
||||
|
||||
// 设置登陆主机的密码
|
||||
session.setPassword(psw);// 设置密码
|
||||
|
||||
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
|
||||
// 设置登陆超时时间
|
||||
session.connect(30000);
|
||||
|
||||
// 创建通信通道
|
||||
return session.openChannel(type);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// String sftpUsername= PropertiesUtilDB.getProperty("backup.username");
|
||||
// String sftpPassword= PropertiesUtilDB.getProperty("backup.password");
|
||||
// String sftpIp= PropertiesUtilDB.getProperty("backup.ip");
|
||||
// int sftpPort= Integer.valueOf(PropertiesUtilDB.getProperty("backup.port"));
|
||||
|
||||
// SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
|
||||
// sftp.login(SFTPUtil.SHELL);
|
||||
// sftp.execCmd(cmd);
|
||||
// sftp.logout();
|
||||
}
|
||||
}
|
||||
20
comm/DB/src/db/util/UUIDGenerator.java
Executable file
20
comm/DB/src/db/util/UUIDGenerator.java
Executable file
@@ -0,0 +1,20 @@
|
||||
package db.util;
|
||||
|
||||
import org.hibernate.id.UUIDHexGenerator;
|
||||
|
||||
public class UUIDGenerator {
|
||||
|
||||
/**
|
||||
* UUID生成器
|
||||
*/
|
||||
private static UUIDHexGenerator UUID_GENERATOR = new UUIDHexGenerator();
|
||||
|
||||
/**
|
||||
* <p>Description: 生成UUID </p>
|
||||
* @return UUID
|
||||
*/
|
||||
public static String getUUID() {
|
||||
return (String) UUID_GENERATOR.generate(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
132
comm/DB/src/db/util/ZipUtils.java
Executable file
132
comm/DB/src/db/util/ZipUtils.java
Executable file
@@ -0,0 +1,132 @@
|
||||
package db.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class ZipUtils {
|
||||
|
||||
/**
|
||||
* logger
|
||||
*/
|
||||
private static Logger logger = LogManager.getLogger(ZipUtils.class);
|
||||
|
||||
/**
|
||||
* <p>Description: 压缩文件 </p>
|
||||
*
|
||||
* @param zname 生成文件名
|
||||
* @param source 待压缩文件
|
||||
*/
|
||||
public static void createZip(String zname, String source) {
|
||||
logger.info("start compressing backup files...");
|
||||
try {
|
||||
File filezip = new File(zname);
|
||||
if (!filezip.exists()) {
|
||||
filezip.createNewFile();
|
||||
}
|
||||
|
||||
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zname));
|
||||
compressFile(zout, "", new File(source));
|
||||
zout.close();
|
||||
logger.info("compress backup files finished");
|
||||
} catch (Exception e) {
|
||||
logger.error("compress backup files error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 压缩文件 </p>
|
||||
*
|
||||
* @param zout ZipOutputStream
|
||||
* @param dir 相对路径
|
||||
* @param source 源文件
|
||||
* @throws IOException ioException
|
||||
*/
|
||||
private static void compressFile(ZipOutputStream zout, String dir, File source) throws IOException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("do compressing file:" + source);
|
||||
}
|
||||
if (source.isDirectory()) {
|
||||
File[] fs = source.listFiles();
|
||||
dir = dir + (dir.length() == 0 ? "" : "/") + source.getName();
|
||||
for (File f : fs) {
|
||||
compressFile(zout, dir, f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dir = dir.length() == 0 ? "" : dir + "/" + source.getName();
|
||||
ZipEntry entry = new ZipEntry(dir);
|
||||
|
||||
// ZipEntry entry = new ZipEntry(source.getName());
|
||||
zout.putNextEntry(entry);
|
||||
FileInputStream fin = new FileInputStream(source);
|
||||
int size = 0;
|
||||
byte[] buf = new byte[10240];
|
||||
while ((size = fin.read(buf, 0, 10240)) != -1) {
|
||||
zout.write(buf, 0, size);
|
||||
}
|
||||
fin.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Description: 解压文件 </p>
|
||||
*
|
||||
* @param source 源文件
|
||||
* @param destdir 目的目录
|
||||
*/
|
||||
public static void unZip(String source, String destdir) {
|
||||
try {
|
||||
logger.info("start decompressing backup files...");
|
||||
FileInputStream fin = new FileInputStream(source);
|
||||
ZipInputStream zin = new ZipInputStream(fin);
|
||||
|
||||
ZipEntry entry = null;
|
||||
while ((entry = zin.getNextEntry()) != null) {
|
||||
|
||||
File filename = new File(destdir + entry.getName());
|
||||
if (logger.isDebugEnabled()) {
|
||||
// System.out.println("正在解压" + entry.getName());
|
||||
logger.debug("do decompressing file:" + entry.getName());
|
||||
}
|
||||
|
||||
File path = new File(filename.getParentFile().getPath()); // 确认目标目录存在、解压文件夹存在
|
||||
if (entry.isDirectory()) {
|
||||
if (!filename.exists()) {
|
||||
filename.mkdirs();
|
||||
}
|
||||
zin.closeEntry();
|
||||
continue;
|
||||
}
|
||||
if (!path.exists()) {
|
||||
path.mkdirs();
|
||||
}
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(filename); // 得到目标文件流
|
||||
|
||||
int size = 0;
|
||||
byte[] buf = new byte[256];
|
||||
while ((size = zin.read(buf)) != -1) { // 每个entry都有一个文件末尾的标识
|
||||
fout.write(buf, 0, size);
|
||||
}
|
||||
zin.closeEntry();
|
||||
fout.close();
|
||||
}
|
||||
|
||||
fin.close();
|
||||
zin.close();
|
||||
// System.out.println("解压完成!");
|
||||
logger.info("decompress backup files finished");
|
||||
} catch (Exception e) {
|
||||
logger.error("decompress backup files error", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
39
comm/DB/src/db/util/jdbc/DBTools.java
Executable file
39
comm/DB/src/db/util/jdbc/DBTools.java
Executable file
@@ -0,0 +1,39 @@
|
||||
package db.util.jdbc;
|
||||
|
||||
import db.util.ConfigUtils;
|
||||
import kernel.util.StringUtils;
|
||||
|
||||
public class DBTools {
|
||||
|
||||
/**
|
||||
* 处理有配置数据库安装目录情况、(通用方法)
|
||||
* <pre>说明:不适用于SQL Server</pre>
|
||||
*
|
||||
* @param cmd 客户端命令
|
||||
* @param suffix 客户端程序后缀
|
||||
* @return 客户端命令 with 执行路径
|
||||
*/
|
||||
public static String formatDBClientCmd(String cmd, String suffix) {
|
||||
String installedPath = ConfigUtils.getDBInstalledPath();
|
||||
if (StringUtils.isNullOrEmpty(installedPath)) {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
return new StringBuffer(formatRuntimeCmdPath(installedPath)) // 空格处理
|
||||
.append("/").append(cmd).append(".").append(suffix).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime CMD 空格路径处理
|
||||
*
|
||||
* @param path 路径
|
||||
* @return 空格前后加\" \"
|
||||
*/
|
||||
public static String formatRuntimeCmdPath(String path) {
|
||||
if (path.indexOf(" ") != -1) {
|
||||
path = path.replaceAll(" ", "\" \""); // 空格处理
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
||||
64
comm/DB/src/db/util/jdbc/MysqlTools.java
Executable file
64
comm/DB/src/db/util/jdbc/MysqlTools.java
Executable file
@@ -0,0 +1,64 @@
|
||||
package db.util.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
|
||||
public class MysqlTools {
|
||||
|
||||
/**
|
||||
* 获取所有数据库表(BASE TABLE)
|
||||
* @param ip 数据库IP地址
|
||||
* @param port 数据库端口
|
||||
* @param databaseName 数据库名
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return 数据库中的所有表
|
||||
*/
|
||||
public static List<String> findAllDBTables(String ip, String port, String databaseName, String username,
|
||||
String password) {
|
||||
final List<String> tables = new ArrayList<String>();
|
||||
|
||||
String sql = "select TABLE_NAME from TABLES where TABLE_SCHEMA = '" + databaseName
|
||||
+ "' and TABLE_TYPE ='BASE TABLE'";
|
||||
JdbcTemplate jt = new JdbcTemplate(createDataSource(ip, port, "information_schema", username, password));
|
||||
jt.query(sql, new RowCallbackHandler() {
|
||||
public void processRow(ResultSet rs) throws SQLException {
|
||||
if (rs != null) {
|
||||
tables.add(rs.getString(1));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立数据库连接
|
||||
* jdbc:mysql://${db.host}:3306
|
||||
* @param ip 数据库IP地址
|
||||
* @param port 数据库端口
|
||||
* @param databaseName 数据库名
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return 数据库连接
|
||||
*/
|
||||
public static BasicDataSource createDataSource(String ip, String port, String databaseName, String username,
|
||||
String password) {
|
||||
BasicDataSource ds = new BasicDataSource();
|
||||
// ds.setDriverClassName(MySQLConfig.DRIVERCLASSNAME);
|
||||
ds.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
ds.setUrl("jdbc:mysql://" + ip + ":" + port + "/" + databaseName + "?characterEncoding=utf8");
|
||||
ds.setUsername(username);
|
||||
ds.setPassword(password);
|
||||
ds.setTestOnBorrow(true);
|
||||
ds.setValidationQuery("select 1 ");
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user