대용량 다운로드 테스트

This commit is contained in:
2026-02-11 16:23:24 +09:00
parent ac13f36663
commit 2d2b55efcd
5 changed files with 150 additions and 70 deletions

View File

@@ -0,0 +1,92 @@
package com.kamco.cd.kamcoback.common.download;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.kamcoback.common.download.dto.DownloadAuditEvent;
import com.kamco.cd.kamcoback.menu.dto.MenuDto;
import com.kamco.cd.kamcoback.menu.service.MenuService;
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Component
@RequiredArgsConstructor
public class DownloadAuditEventListener {
private final AuditLogRepository auditLogRepository;
private final MenuService menuService;
private final ObjectMapper objectMapper;
@Async("auditLogExecutor")
@Transactional(propagation = Propagation.REQUIRES_NEW)
@EventListener
public void onDownloadAudit(DownloadAuditEvent ev) {
try {
String menuUid = resolveMenuUid(ev.normalizedUri());
if (menuUid == null) {
// menuUid null 불가 -> 스킵
log.warn(
"MenuUid not resolved. skip audit. uri={}, normalized={}",
ev.requestUri(),
ev.normalizedUri());
return;
}
AuditLogEntity logEntity =
AuditLogEntity.forFileDownload(
ev.userId(), ev.requestUri(), menuUid, ev.ip(), ev.status(), ev.downloadUuid());
auditLogRepository.save(logEntity);
} catch (Exception e) {
// 본 요청과 분리되어야 함
log.warn("Download audit save failed. uri={}, err={}", ev.requestUri(), e.toString());
}
}
private String resolveMenuUid(String normalizedUri) {
try {
List<?> list = menuService.getFindAll();
List<MenuDto.Basic> basics =
list.stream()
.map(
item -> {
if (item instanceof LinkedHashMap<?, ?> map) {
return objectMapper.convertValue(map, MenuDto.Basic.class);
} else if (item instanceof MenuDto.Basic dto) {
return dto;
}
return null;
})
.filter(Objects::nonNull)
.toList();
MenuDto.Basic basic =
basics.stream()
.filter(m -> m.getMenuUrl() != null && normalizedUri.startsWith(m.getMenuUrl()))
.max(Comparator.comparingInt(m -> m.getMenuUrl().length()))
.orElse(null);
if (basic == null) return null;
String menuUidStr = basic.getMenuUid(); // ← String
if (menuUidStr == null || menuUidStr.isBlank()) return null;
return menuUidStr; // ← Long 변환
} catch (Exception e) {
return null;
}
}
}

View File

@@ -0,0 +1,11 @@
package com.kamco.cd.kamcoback.common.download.dto;
import java.util.UUID;
public record DownloadAuditEvent(
Long userId,
String requestUri,
String normalizedUri,
String ip,
int status,
UUID downloadUuid) {}