feat:增加备份管理模块
This commit is contained in:
parent
2fcbb65a6f
commit
87ee0bd55c
26
flyfish-backup/pom.xml
Normal file
26
flyfish-backup/pom.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>flyfish-framework</artifactId>
|
||||||
|
<groupId>com.flyfish.framework</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>flyfish-backup</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.flyfish.framework</groupId>
|
||||||
|
<artifactId>flyfish-web</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.flyfish.framework.backup.controller;
|
||||||
|
|
||||||
|
import com.flyfish.framework.backup.domain.Backup;
|
||||||
|
import com.flyfish.framework.backup.scheduler.BackupScheduler;
|
||||||
|
import com.flyfish.framework.bean.Result;
|
||||||
|
import com.flyfish.framework.controller.reactive.ReactiveBaseController;
|
||||||
|
import com.flyfish.framework.domain.base.NameLikeQo;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备份controller
|
||||||
|
*
|
||||||
|
* @author wangyu
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("backups")
|
||||||
|
public class BackupController extends ReactiveBaseController<Backup, NameLikeQo<Backup>> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BackupScheduler backupScheduler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 立即创建备份
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping("task")
|
||||||
|
public Result<String> createTask() {
|
||||||
|
backupScheduler.backup();
|
||||||
|
return Result.accept("已创建备份,完成后会出现在列表中,请稍后刷新再试。");
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package com.flyfish.framework.domain.po;
|
package com.flyfish.framework.backup.domain;
|
||||||
|
|
||||||
import com.flyfish.framework.domain.base.AuditDomain;
|
import com.flyfish.framework.domain.base.AuditDomain;
|
||||||
import com.flyfish.framework.enums.NamedEnum;
|
import com.flyfish.framework.enums.NamedEnum;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统备份
|
* 系统备份
|
||||||
@ -13,6 +14,7 @@ import lombok.Setter;
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@Document(collection = "backups")
|
||||||
public class Backup extends AuditDomain {
|
public class Backup extends AuditDomain {
|
||||||
|
|
||||||
// 文件路径
|
// 文件路径
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.flyfish.framework.backup.repository;
|
||||||
|
|
||||||
|
import com.flyfish.framework.backup.domain.Backup;
|
||||||
|
import com.flyfish.framework.repository.DefaultReactiveRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备份仓库
|
||||||
|
*
|
||||||
|
* @author wangyu
|
||||||
|
*/
|
||||||
|
public interface BackupRepository extends DefaultReactiveRepository<Backup> {
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
package com.flyfish.framework.scheduler;
|
package com.flyfish.framework.backup.scheduler;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,8 +1,8 @@
|
|||||||
package com.flyfish.framework.scheduler;
|
package com.flyfish.framework.backup.scheduler;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.flyfish.framework.backup.domain.Backup;
|
||||||
import com.flyfish.framework.domain.base.DomainService;
|
import com.flyfish.framework.domain.base.DomainService;
|
||||||
import com.flyfish.framework.domain.po.Backup;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -20,6 +20,7 @@ import org.springframework.util.unit.DataSize;
|
|||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.channels.AsynchronousFileChannel;
|
import java.nio.channels.AsynchronousFileChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -29,6 +30,7 @@ import java.nio.file.StandardOpenOption;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,9 +77,8 @@ public class BackupScheduler {
|
|||||||
public void backup() {
|
public void backup() {
|
||||||
// 本次备份任务代号
|
// 本次备份任务代号
|
||||||
String code = UUID.randomUUID().toString();
|
String code = UUID.randomUUID().toString();
|
||||||
// 本次备份父目录
|
// 本次备份父目录,出错时替换目录,保证备份成功
|
||||||
String parent = backupPath + "/" + code;
|
String parent = createIfNotExists(backupPath + "/" + code);
|
||||||
createIfNotExists(parent);
|
|
||||||
// 开始备份,先构造一个指示器
|
// 开始备份,先构造一个指示器
|
||||||
Backup backup = new Backup();
|
Backup backup = new Backup();
|
||||||
backup.setCreateTime(new Date());
|
backup.setCreateTime(new Date());
|
||||||
@ -85,6 +86,8 @@ public class BackupScheduler {
|
|||||||
backup.setCode(code);
|
backup.setCode(code);
|
||||||
backup.setStatus(Backup.Status.RUNNING);
|
backup.setStatus(Backup.Status.RUNNING);
|
||||||
backup.setFilepath(parent + "/back.zip");
|
backup.setFilepath(parent + "/back.zip");
|
||||||
|
// 数据大小计数器
|
||||||
|
AtomicLong sizeCounter = new AtomicLong(0);
|
||||||
// 开始备份
|
// 开始备份
|
||||||
operations.save(backup)
|
operations.save(backup)
|
||||||
.thenMany(Flux.fromIterable(this.collections))
|
.thenMany(Flux.fromIterable(this.collections))
|
||||||
@ -98,7 +101,9 @@ public class BackupScheduler {
|
|||||||
BackupIndex index = new BackupIndex();
|
BackupIndex index = new BackupIndex();
|
||||||
index.setId(code);
|
index.setId(code);
|
||||||
index.setItems(list.stream().map(content -> {
|
index.setItems(list.stream().map(content -> {
|
||||||
DataSize size = DataSize.parse(new String(content.getContent(), StandardCharsets.UTF_8));
|
long currentSize = content.getContent().length;
|
||||||
|
sizeCounter.addAndGet(currentSize);
|
||||||
|
DataSize size = DataSize.ofBytes(currentSize);
|
||||||
BackupIndex.BackupItem item = new BackupIndex.BackupItem();
|
BackupIndex.BackupItem item = new BackupIndex.BackupItem();
|
||||||
item.setCollection(content.getCollection());
|
item.setCollection(content.getCollection());
|
||||||
item.setPath(parent + "/" + content.getCollection() + ".json");
|
item.setPath(parent + "/" + content.getCollection() + ".json");
|
||||||
@ -112,6 +117,7 @@ public class BackupScheduler {
|
|||||||
backup.setLog("成功备份");
|
backup.setLog("成功备份");
|
||||||
backup.setPeriod(new Date().getTime() - backup.getCreateTime().getTime());
|
backup.setPeriod(new Date().getTime() - backup.getCreateTime().getTime());
|
||||||
backup.setStatus(Backup.Status.SUCCESS);
|
backup.setStatus(Backup.Status.SUCCESS);
|
||||||
|
backup.setSize(DataSize.ofBytes(sizeCounter.get()).toKilobytes() + "KB");
|
||||||
return operations.save(backup);
|
return operations.save(backup);
|
||||||
}))
|
}))
|
||||||
.subscribe(v -> {
|
.subscribe(v -> {
|
||||||
@ -131,11 +137,17 @@ public class BackupScheduler {
|
|||||||
* @param filepath 路径
|
* @param filepath 路径
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
private void createIfNotExists(String filepath) {
|
private String createIfNotExists(String filepath) {
|
||||||
Path path = Paths.get(filepath);
|
Path path = Paths.get(filepath);
|
||||||
if (!Files.exists(path)) {
|
if (!Files.exists(path)) {
|
||||||
Files.createDirectories(path);
|
try {
|
||||||
|
Files.createDirectories(path);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
return createIfNotExists(System.getProperty("user.home") + filepath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,7 +169,7 @@ public class BackupScheduler {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
private Mono<Void> write(byte[] content, String path) {
|
private Mono<Void> write(byte[] content, String path) {
|
||||||
return Mono.fromCallable(() -> AsynchronousFileChannel.open(Paths.get(path), StandardOpenOption.WRITE))
|
return Mono.fromCallable(() -> AsynchronousFileChannel.open(Files.createFile(Paths.get(path)), StandardOpenOption.WRITE))
|
||||||
.flatMapMany(channel -> DataBufferUtils.write(Mono.just(factory.wrap(content)), channel, 0))
|
.flatMapMany(channel -> DataBufferUtils.write(Mono.just(factory.wrap(content)), channel, 0))
|
||||||
.then();
|
.then();
|
||||||
}
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.flyfish.framework.backup.service;
|
||||||
|
|
||||||
|
import com.flyfish.framework.backup.domain.Backup;
|
||||||
|
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备份服务
|
||||||
|
*
|
||||||
|
* @author wangyu
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class BackupService extends BaseReactiveServiceImpl<Backup> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复指定备份
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public Mono<Void> restore(String id) {
|
||||||
|
return Mono.empty();
|
||||||
|
}
|
||||||
|
}
|
1
pom.xml
1
pom.xml
@ -46,6 +46,7 @@
|
|||||||
<module>flyfish-dict</module>
|
<module>flyfish-dict</module>
|
||||||
<module>flyfish-form</module>
|
<module>flyfish-form</module>
|
||||||
<module>flyfish-approval</module>
|
<module>flyfish-approval</module>
|
||||||
|
<module>flyfish-backup</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
Loading…
Reference in New Issue
Block a user