Skip to content

Commit a458e07

Browse files
committed
feat: DB 백업 기능 추가
1 parent f2b52f1 commit a458e07

5 files changed

Lines changed: 425 additions & 5 deletions

File tree

build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ afterEvaluate {
193193
}
194194
}
195195

196-
// 커버리지 검증 (현실적 기준)
196+
// 커버리지 검증
197197
tasks.named('jacocoTestCoverageVerification') {
198198
violationRules {
199199
rule {
@@ -203,13 +203,13 @@ tasks.named('jacocoTestCoverageVerification') {
203203
limit {
204204
counter = 'LINE'
205205
value = 'COVEREDRATIO'
206-
minimum = 0.00
206+
minimum = 0.4
207207
}
208208

209209
limit {
210210
counter = 'BRANCH'
211211
value = 'COVEREDRATIO'
212-
minimum = 0.00
212+
minimum = 0.8
213213
}
214214

215215
excludes = [
@@ -230,7 +230,7 @@ tasks.named('jacocoTestCoverageVerification') {
230230
}
231231
}
232232

233-
// SonarQube 태스크 의존성 설정 (최신 API)
233+
// SonarQube 태스크 의존성 설정
234234
tasks.named('sonar') {
235235
dependsOn tasks.compileJava, tasks.compileTestJava, tasks.test, tasks.jacocoTestReport
236236

@@ -246,7 +246,7 @@ tasks.named('sonar') {
246246

247247
}
248248

249-
// 커스텀 태스크들 (최신 Task API 사용)
249+
250250
tasks.register('testOnly') {
251251
group = 'verification'
252252
description = "테스트만 실행 (실패 무시)"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.neeis.neeis.global.backup;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
5+
import org.springframework.http.ResponseEntity;
6+
import org.springframework.web.bind.annotation.*;
7+
8+
@RestController
9+
@RequestMapping("/admin/backup")
10+
@RequiredArgsConstructor
11+
@ConditionalOnProperty(name = "backup.enabled", havingValue = "true")
12+
public class BackupController {
13+
14+
private final DatabaseBackupService backupService;
15+
16+
@PostMapping("/manual")
17+
public ResponseEntity<String> manualBackup() {
18+
boolean success = backupService.performBackup();
19+
return success ?
20+
ResponseEntity.ok("백업이 성공적으로 완료되었습니다.") :
21+
ResponseEntity.internalServerError().body("백업 실행 중 오류가 발생했습니다.");
22+
}
23+
24+
@GetMapping("/status")
25+
public ResponseEntity<BackupStatus> getBackupStatus() {
26+
return ResponseEntity.ok(backupService.getBackupStatus());
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.neeis.neeis.global.backup;
2+
3+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.scheduling.annotation.EnableScheduling;
6+
import org.springframework.scheduling.annotation.SchedulingConfigurer;
7+
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
8+
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
9+
10+
@Configuration
11+
@EnableScheduling
12+
@ConditionalOnProperty(name = "backup.enabled", havingValue = "true", matchIfMissing = false)
13+
public class BackupSchedulerConfig implements SchedulingConfigurer {
14+
15+
@Override
16+
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
17+
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
18+
taskScheduler.setPoolSize(2); // 백업용 스레드 풀 크기
19+
taskScheduler.setThreadNamePrefix("backup-scheduler-");
20+
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
21+
taskScheduler.setAwaitTerminationSeconds(60);
22+
taskScheduler.initialize();
23+
24+
taskRegistrar.setTaskScheduler(taskScheduler);
25+
}
26+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.neeis.neeis.global.backup;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
import java.time.LocalDateTime;
6+
7+
@Getter
8+
@Builder
9+
public class BackupStatus {
10+
private final LocalDateTime lastBackupTime;
11+
private final int backupCount;
12+
private final long totalSize;
13+
14+
public String getTotalSizeFormatted() {
15+
if (totalSize < 1024) {
16+
return totalSize + " B";
17+
} else if (totalSize < 1024 * 1024) {
18+
return String.format("%.1f KB", totalSize / 1024.0);
19+
} else if (totalSize < 1024 * 1024 * 1024) {
20+
return String.format("%.1f MB", totalSize / (1024.0 * 1024.0));
21+
} else {
22+
return String.format("%.1f GB", totalSize / (1024.0 * 1024.0 * 1024.0));
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)