Skip to content

Commit

Permalink
CLAP-310 Refactor: 예외 처리 추가
Browse files Browse the repository at this point in the history
<footer>
- 관련: #380
  • Loading branch information
joowojr committed Feb 7, 2025
1 parent a16da66 commit 941443f
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package clap.server.adapter.outbound.infrastructure.clamav;

import clap.server.exception.ClamAVException;
import clap.server.exception.code.FileErrorcode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
Expand All @@ -20,10 +22,10 @@
@Component
@RequiredArgsConstructor
public class ClamAVScanner {
private final ClamavClient client;
private final ClamavClient clamavClient;
private final ThreadPoolTaskExecutor clamavExecutor;

public CompletableFuture<Boolean> scanFileAsync(String filePath) {
public CompletableFuture<Void> scanFileAsync(String filePath) {
return CompletableFuture.supplyAsync(() -> {
Path originalPath = Paths.get(filePath);
Path tempPath = null;
Expand All @@ -35,25 +37,23 @@ public CompletableFuture<Boolean> scanFileAsync(String filePath) {

Files.copy(originalPath, tempPath, StandardCopyOption.REPLACE_EXISTING);

ScanResult result = client.scan(tempPath);
ScanResult result = clamavClient.scan(tempPath);
if (result instanceof ScanResult.OK) {
log.info("파일이 안전합니다: {}", originalFileName);
return true;
} else if (result instanceof ScanResult.VirusFound virusFound) {
log.warn("바이러스 발견: {} in {}", virusFound.getFoundViruses(), originalFileName);
return false;
throw new ClamAVException(FileErrorcode.VIRUS_FILE_DETECTED);
} else {
log.warn("알 수 없는 스캔 결과 타입: {}", result.getClass().getName());
throw new ClamAVException(FileErrorcode.FILE_SCAN_FAILED);
}
log.warn("알 수 없는 스캔 결과 타입: {}", result.getClass().getName());
return false;
return null;
} catch (IOException e) {
log.error("파일 처리 중 오류 발생: {}", filePath, e);
return false;
throw new ClamavException(e);
} catch (ClamavException e) {
log.error("ClamAV 스캔 중 오류 발생: {}", filePath, e);
return false;
} catch (Exception e) {
log.error("예상치 못한 오류 발생: {}", filePath, e);
return false;
throw new ClamavException(e);
} finally {
if (tempPath != null) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package clap.server.adapter.outbound.infrastructure.clamav;

import clap.server.exception.AdapterException;
import clap.server.exception.ClamAVException;
import clap.server.exception.code.FileErrorcode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -16,6 +17,7 @@
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@Slf4j
Expand All @@ -37,6 +39,10 @@ public List<MultipartFile> scanFiles(List<MultipartFile> files) {
.collect(Collectors.toList());
}

public MultipartFile scanSingleFile(MultipartFile file) throws ExecutionException, InterruptedException {
return scanFile(file).get();
}

@Async("clamavExecutor")
protected CompletableFuture<MultipartFile> scanFile(MultipartFile file) {
return CompletableFuture.supplyAsync(() -> {
Expand All @@ -46,14 +52,11 @@ protected CompletableFuture<MultipartFile> scanFile(MultipartFile file) {
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, tempPath, StandardCopyOption.REPLACE_EXISTING);
}

boolean isSafe = clamAVScanner.scanFileAsync(tempPath.toString()).get();
if (isSafe) {
return file;
} else {
log.warn("Virus detected in file: {}", file.getOriginalFilename());
throw new AdapterException(FileErrorcode.VIRUS_FILE_DETECTED);
}
clamAVScanner.scanFileAsync(tempPath.toString()).get();
return file;
} catch (ClamAVException e) {
log.warn("Virus detected in file: {}", file.getOriginalFilename());
throw new AdapterException(FileErrorcode.FILE_SCAN_FAILED);
} catch (Exception e) {
log.error("Failed to scan file: {}", file.getOriginalFilename(), e);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.concurrent.ExecutionException;

public interface FileVirusScannerPort {
List<MultipartFile> scanFiles(List<MultipartFile> files);
MultipartFile scanSingleFile(MultipartFile file) throws ExecutionException, InterruptedException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public CreateTaskResponse createTask(Long requesterId, CreateTaskRequest createT
}

@Override
@Transactional
public CreateTaskResponse createTaskWithScanner(Long requesterId, CreateTaskRequest createTaskRequest, List<MultipartFile> files) {
Member member = memberService.findActiveMember(requesterId);
Category category = categoryService.findById(createTaskRequest.categoryId());
Expand All @@ -73,7 +74,7 @@ public CreateTaskResponse createTaskWithScanner(Long requesterId, CreateTaskRequ
}

private void saveAttachments(List<MultipartFile> files, Task task) {
List<String> fileUrls = s3UploadPort.uploadFiles(FilePathPolicy.TASK_IMAGE, files);
List<String> fileUrls = s3UploadPort.uploadFiles(FilePathPolicy.TASK_FILE, files);
List<Attachment> attachments = AttachmentMapper.toTaskAttachments(task, files, fileUrls);
commandAttachmentPort.saveAll(attachments);
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/clap/server/exception/ClamAVException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package clap.server.exception;

import clap.server.exception.code.BaseErrorCode;

public class ClamAVException extends BaseException {
public ClamAVException(BaseErrorCode code) {
super(code);
}

public BaseErrorCode getErrorCode() {
return (BaseErrorCode)super.getCode();
}
}
3 changes: 2 additions & 1 deletion src/main/java/clap/server/exception/code/FileErrorcode.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
public enum FileErrorcode implements BaseErrorCode {
FILE_UPLOAD_REQUEST_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FILE_001", "파일 업로드에 실패하였습니다."),
UNSUPPORTED_FILE_TYPE(HttpStatus.BAD_REQUEST, "FILE_002", "유효하지 않은 파일 유형입니다."),
VIRUS_FILE_DETECTED(HttpStatus.BAD_REQUEST, "FILE_003", "안전하지 않은 파일이 감지되었습니다.")
VIRUS_FILE_DETECTED(HttpStatus.BAD_REQUEST, "FILE_003", "안전하지 않은 파일이 감지되었습니다."),
FILE_SCAN_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FILE_004", "파일 스캔에 실패하였습니다.")
;

private final HttpStatus httpStatus;
Expand Down

0 comments on commit 941443f

Please sign in to comment.