diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/obp/ObpGwMetricService.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/obp/ObpGwMetricService.java index be973ab..52d0dea 100644 --- a/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/obp/ObpGwMetricService.java +++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/apim/obp/ObpGwMetricService.java @@ -43,6 +43,13 @@ public class ObpGwMetricService { return repository.findByTimesliceBetween(startTime, endTime); } + /** + * 특정 시간대 이후의 모든 GwMetric 데이터 조회 + */ + public List findByTimesliceGreaterThanEqual(LocalDateTime timeslice) { + return repository.findByTimesliceGreaterThanEqual(timeslice); + } + /** * 엔티티 저장 (INSERT 또는 UPDATE) */ diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricAfterDTO.java b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricAfterDTO.java new file mode 100644 index 0000000..2852cf6 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricAfterDTO.java @@ -0,0 +1,96 @@ +package com.eactive.eai.rms.onl.apim.obp; + +import com.eactive.apim.portal.obp.entity.ObpGwMetric; +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * ObpGwMetric JSON 응답 DTO (after-timeslice 엔드포인트용) + * + *

예시 출력 형식에 맞춤:

+ *
+ * {
+ *   "apiId": "1ba56b82-a9c9-41e2-b3ab-ff9377667d56",
+ *   "apiName": "[해외송금] 가상계좌 입금실패 정보조회",
+ *   "apiRoutingUri": "/api/obs/remittance/remittancefail*",
+ *   "orgId": "ORG001",
+ *   "partnerCode": "000008-01",
+ *   "appId": "APP001",
+ *   "appKey": "l7xx2fd7efc523794be5a1b126873a5de613",
+ *   "requestUri": "-1",
+ *   "timeslice": "2025-12-02T03:00:00.000+0000",
+ *   "attemptedCount": 3,
+ *   "completedCount": 3
+ * }
+ * 
+ */ +@Data +public class ObpGwMetricAfterDTO { + + private static final DateTimeFormatter ISO8601_MILLIS_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'+0000'"); + + @SerializedName("apiId") + private String apiId; + + @SerializedName("apiName") + private String apiName; + + @SerializedName("apiRoutingUri") + private String apiRoutingUri; + + @SerializedName("orgId") + private String orgId; + + @SerializedName("partnerCode") + private String partnerCode; + + @SerializedName("appId") + private String appId; + + @SerializedName("appKey") + private String appKey; + + @SerializedName("requestUri") + private String requestUri; + + @SerializedName("timeslice") + private String timeslice; + + @SerializedName("attemptedCount") + private Long attemptedCount; + + @SerializedName("completedCount") + private Long completedCount; + + /** + * Entity → DTO 변환 + */ + public static ObpGwMetricAfterDTO from(ObpGwMetric entity) { + ObpGwMetricAfterDTO dto = new ObpGwMetricAfterDTO(); + dto.setApiId(entity.getApiId()); + dto.setApiName(entity.getApiName()); + dto.setApiRoutingUri(entity.getUri()); + dto.setOrgId(entity.getOrgId()); + dto.setPartnerCode(entity.getPartnerCode()); + dto.setAppId(entity.getAppId()); + dto.setAppKey(entity.getClientId()); + dto.setRequestUri(entity.getRequestUri()); + dto.setTimeslice(formatTimeslice(entity.getTimeslice())); + dto.setAttemptedCount(entity.getAttemptedCount()); + dto.setCompletedCount(entity.getCompletedCount()); + return dto; + } + + /** + * timeslice를 ISO8601 형식 (밀리초 포함) + UTC 시간대로 변환 + * 예: 2025-12-02T03:00:00.000+0000 + */ + private static String formatTimeslice(LocalDateTime timeslice) { + if (timeslice == null) return null; + return timeslice.format(ISO8601_MILLIS_FORMATTER); + } +} diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricController.java b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricController.java index fb3168b..df92b9b 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricController.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricController.java @@ -81,6 +81,52 @@ public class ObpGwMetricController implements InterceptorSkipController { } } + /** + * 특정 시간대 이후의 GwMetric 데이터 조회 + * + * @param datetime 조회 시작 시간대 (형식: yyyy-MM-dd_HH:mm:ss) + * @return JSON Array (해당 시간대 이후의 모든 지표) + */ + @RequestMapping( + value = "/kjb/gw-metrics/after-timeslice/{datetime}", + produces = "application/json;charset=utf-8" + ) + @ResponseBody + public String getGwMetricsAfterTimeslice(@PathVariable("datetime") String datetime) { + log.debug("GwMetric after-timeslice 조회 요청: datetime={}", datetime); + long startTime = System.currentTimeMillis(); + + try { + // Path 파라미터 파싱 + LocalDateTime targetTime = LocalDateTime.parse(datetime, PATH_FORMATTER); + LocalDateTime timeslice = targetTime.withMinute(0).withSecond(0).withNano(0); + + // 조회 + List metrics = obpGwMetricManService.findByTimesliceAfter(timeslice); + + // JSON 변환 (GSON) + Gson gson = new GsonBuilder() + .serializeNulls() + .create(); + + String json = gson.toJson(metrics); + + // 응답 크기 계산 (UTF-8 기준) + int jsonBytes = json.getBytes(StandardCharsets.UTF_8).length; + String jsonSize = formatByteSize(jsonBytes); + + long elapsed = System.currentTimeMillis() - startTime; + log.info("GwMetric after-timeslice 조회 완료: datetime={}, count={}, size={}, elapsed={}ms", + datetime, metrics.size(), jsonSize, elapsed); + + return json; + + } catch (Exception e) { + log.error("GwMetric after-timeslice 조회 실패: datetime={}", datetime, e); + throw e; + } + } + /** * 바이트 크기를 읽기 쉬운 형식으로 변환 * 예: 1024 -> "1.0 KB", 1048576 -> "1.0 MB" diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java index 0675162..86c6167 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java @@ -279,4 +279,18 @@ public class ObpGwMetricManService extends BaseService { .map(ObpGwMetricDTO::from) .collect(Collectors.toList()); } + + /** + * 특정 시간대 이후의 GwMetric 데이터 조회 (REST API용) + * after-timeslice 엔드포인트에서 사용 + */ + public List findByTimesliceAfter(LocalDateTime timeslice) { + DataSourceContextHolder.setDataSourceType( + DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING)); + + List entities = obpGwMetricService.findByTimesliceGreaterThanEqual(timeslice); + return entities.stream() + .map(ObpGwMetricAfterDTO::from) + .collect(Collectors.toList()); + } } diff --git a/src/main/resources/com/eactive/eai/apim/obp/ObpGwMetric-oracle.xml b/src/main/resources/com/eactive/eai/apim/obp/ObpGwMetric-oracle.xml index b187769..05d5b0d 100644 --- a/src/main/resources/com/eactive/eai/apim/obp/ObpGwMetric-oracle.xml +++ b/src/main/resources/com/eactive/eai/apim/obp/ObpGwMetric-oracle.xml @@ -44,7 +44,7 @@ SUM(CASE WHEN LOGPRCSSSERNO = '400' AND (RSPNSERRCDNAME IS NULL OR RSPNSERRCDNAME LIKE 'ESB%') THEN 1 ELSE 0 END) AS COMPLETED_COUNT, - MAX(EAISVCSERNO) AS EAI_SVC_SERNO + MAX(TRIM(EAISVCSERNO)) AS EAI_SVC_SERNO FROM $schemaId$.$tableName$ WHERE EAIBZWKDSTCD = #bzwkCode# AND MSGDPSTYMS BETWEEN #startTime# AND #endTime#