zj
2024-06-03 3603ecb207f7e712c635f19531e05fac4d19e53f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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);
        }
    }
 
}