대용량 다운로드 테스트
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
Reference in New Issue
Block a user