package com.eactive.ext.kjb.web; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import com.eactive.eai.rms.common.datasource.DataSourceContextHolder; import com.eactive.eai.rms.common.datasource.DataSourceTypeManager; import com.eactive.eai.rms.common.interceptor.InterceptorSkipController; import com.eactive.eai.rms.data.entity.onl.logger.ApiLogDTO; import com.eactive.eai.rms.data.entity.onl.logger.ApiMessageLogDTO; import com.eactive.eai.rms.data.entity.onl.logger.EAILogService; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j @Controller @RequiredArgsConstructor public class ApiTransactionLogController implements InterceptorSkipController { private final EAILogService eaiLogService; private final ObjectMapper objectMapper = new ObjectMapper(); @GetMapping("/api/transaction/log.do") @PostMapping("/api/transaction/log.do") public ResponseEntity getApiLog(String txDate, String apiServiceNumber) { DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW)); // txDate가 없으면 오늘 날짜 설정 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate searchDate; if (StringUtils.hasText(txDate)) { searchDate = LocalDate.parse(txDate, formatter); } else { searchDate = LocalDate.now(); } // 최대 10일 전까지 조회 시도 ApiLogDTO dto = null; for (int i = 0; i < 10; i++) { String searchDateStr = searchDate.format(formatter); dto = eaiLogService.getApiLog(searchDateStr, apiServiceNumber); // 결과가 있으면 종료 if (dto != null && dto.getLogs() != null && !dto.getLogs().isEmpty()) { break; } // 하루 전으로 이동 searchDate = searchDate.minusDays(1); } return ResponseEntity.ok(convertToUI(dto)); } private ApiLogUI convertToUI(ApiLogDTO dto) { ApiLogUI ui = new ApiLogUI(); ui.setApiServiceNumber(dto.getApiServiceNumber()); ui.setTxDate(dto.getTxDate()); ui.setTotalProcessingTime(dto.getTotalProcessingTime()); if (dto.getLogs() != null) { List uiLogs = dto.getLogs().stream().map(this::convertMessageToUI) .collect(Collectors.toList()); ui.setLogs(uiLogs); } return ui; } private ApiMessageLogUI convertMessageToUI(ApiMessageLogDTO dto) { ApiMessageLogUI ui = new ApiMessageLogUI(); ui.setApiServiceNumber(dto.getApiServiceNumber()); ui.setProcessNumber(dto.getProcessNumber()); ui.setTxDate(dto.getTxDate()); ui.setUrl(dto.getUrl()); ui.setQueryString(dto.getQueryString()); ui.setClientId(dto.getClientId()); ui.setMethod(dto.getMethod()); ui.setHttpStatus(dto.getHttpStatus()); ui.setExdata(dto.getExdata()); ui.setProcessingTime(dto.getProcessingTime()); ui.setGuid(dto.getKeymgtmsgctnt()); // header: JSON 문자열 → Map if (dto.getHeader() != null) { try { List> headerList = objectMapper.readValue(dto.getHeader(), new TypeReference>>() { }); Map headerMap = new HashMap<>(); for (Map headerItem : headerList) { String name = headerItem.get("name"); String value = headerItem.get("value"); if (name != null) { headerMap.put(name, value); } } // header에서 client*id 패턴 추출 (정규식, ignoreCase) for (Map.Entry entry : headerMap.entrySet()) { if (entry.getKey() != null && entry.getKey().matches("(?i)client.*id")) { ui.setClientId(entry.getValue()); break; } } ui.setHeader(headerMap); } catch (Exception e) { log.error("Failed to parse header JSON: {}", dto.getHeader(), e); } } // body: JSON 문자열 → Object if (dto.getBody() != null) { try { Object bodyObject = objectMapper.readValue(dto.getBody(), Object.class); ui.setBody(bodyObject); } catch (Exception e) { // JSON 파싱 실패 시 원본 문자열 사용 ui.setBody(dto.getBody()); } } return ui; } }