API 통계 화면 정리
eapim-admin CI / build (push) Has been cancelled

This commit is contained in:
eastargh
2026-08-31 10:47:15 +09:00
parent 9cdfad1317
commit 927ef830ac
17 changed files with 354 additions and 90 deletions
@@ -57,19 +57,19 @@ public class ApiUseStatsService
String dataSql = "";
if ("ORG".equals(search.getSearchType())) {
dataSql = "SELECT NVL(NVL(B.ORGNAME, D.ORG_NAME),'미분류') AS ORGNAME";
dataSql = "SELECT NVL(NVL(B.ORGNAME, D.ORG_NAME),'미분류') AS ORGNAME, '' AS APIDESC";
dataSql += getQueryBody(search);
dataSql += " GROUP BY NVL(NVL(B.ORGNAME, D.ORG_NAME),'미분류')";
dataSql += " ORDER BY ORGNAME";
}
else if ("API".equals(search.getSearchType())) {
dataSql = "SELECT A.API_NAME ";
dataSql = "SELECT A.API_NAME, A.EAISVCDESC ";
dataSql += getQueryBody(search);
dataSql += " GROUP BY A.API_NAME";
dataSql += " GROUP BY A.API_NAME, A.EAISVCDESC ";
dataSql += " ORDER BY API_NAME";
}
else if ("DATE".equals(search.getSearchType())) {
dataSql = "SELECT TO_CHAR(STAT_TIME,'YYYY-MM-DD') AS STAT_TIME ";
dataSql = "SELECT TO_CHAR(STAT_TIME,'YYYY-MM-DD') AS STAT_TIME, '' AS APIDESC ";
dataSql += getQueryBody(search);
dataSql += " GROUP BY TO_CHAR(STAT_TIME,'YYYY-MM-DD')";
dataSql += " ORDER BY STAT_TIME";
@@ -85,7 +85,7 @@ public class ApiUseStatsService
StringBuilder where = buildNativeWhere(search);
String totalSql;
totalSql = "SELECT '합계' AS ORGNAME ";
totalSql = "SELECT '합계' AS ORGNAME, '' AS APIDESC ";
totalSql += getQueryBody(search);
Query totalQuery = entityManager.createNativeQuery(totalSql);
@@ -109,6 +109,7 @@ public class ApiUseStatsService
+ " FROM ("
+ " SELECT A.STAT_TIME "
+ " , A.API_NAME"
+ " , C.EAISVCDESC"
+ " , A.CLIENT_ID "
+ " , A.TOTAL_CNT"
+ " , A.SUCCESS_CNT"
@@ -118,13 +119,13 @@ public class ApiUseStatsService
+ " , A.MIN_RESP_TIME"
+ " , A.MAX_RESP_TIME"
+ " , CASE WHEN API_NAME LIKE '%1' THEN SUBSTR(OUTBOUND_ADAPTER,2,3) ELSE SUBSTR(INBOUND_ADAPTER,2,3) END AS ORG_CODE"
+ " FROM API_STATS_DAY A "
+ " FROM API_STATS_DAY A LEFT OUTER JOIN TSEAIHE01 C ON A.API_NAME = C.EAISVCNAME "
+ " WHERE A.STAT_TIME >= :searchStartDate "
+ " AND A.STAT_TIME <= :searchEndDate ";
if (StringUtils.isNotBlank(search.getSearchApiName())) {
dataSql += " AND A.API_NAME LIKE :searchApiName ";
dataSql += " AND UPPER(A.API_NAME) LIKE :searchApiName ";
}
dataSql += " ) A"
@@ -160,15 +161,16 @@ public class ApiUseStatsService
private ApiStatsUI toVO(Object[] row) {
ApiStatsUI vo = new ApiStatsUI();
vo.setOrgName(StringUtils.toString(row[0]));
vo.setTotalCnt(StringUtils.toLong(row[1]));
vo.setSuccessCnt(StringUtils.toLong(row[2]));
vo.setSuccessRate(StringUtils.toDecimal(row[3]).setScale(2, RoundingMode.HALF_UP));
vo.setFailRate(StringUtils.toDecimal(row[4]).setScale(2, RoundingMode.HALF_UP));
vo.setTimeoutCnt(StringUtils.toLong(row[5]));
vo.setSystemErrCnt(StringUtils.toLong(row[6]));
vo.setAvgRespTime(StringUtils.toDecimal(row[7]));
vo.setMinRespTime(StringUtils.toDecimal(row[8]));
vo.setMaxRespTime(StringUtils.toDecimal(row[9]));
vo.setApiDesc(StringUtils.toString(row[1]));
vo.setTotalCnt(StringUtils.toLong(row[2]));
vo.setSuccessCnt(StringUtils.toLong(row[3]));
vo.setSuccessRate(StringUtils.toDecimal(row[4]).setScale(2, RoundingMode.HALF_UP));
vo.setFailRate(StringUtils.toDecimal(row[5]).setScale(2, RoundingMode.HALF_UP));
vo.setTimeoutCnt(StringUtils.toLong(row[6]));
vo.setSystemErrCnt(StringUtils.toLong(row[7]));
vo.setAvgRespTime(StringUtils.toDecimal(row[8]));
vo.setMinRespTime(StringUtils.toDecimal(row[9]));
vo.setMaxRespTime(StringUtils.toDecimal(row[10]));
return vo;
}
@@ -4,6 +4,8 @@ import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@@ -18,7 +20,10 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsDay;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsDayService;
import com.eactive.ext.kjb.statistics.mapping.ApiStatsUIMapper;
@@ -38,6 +43,7 @@ public class ApiStatsDayController {
private final ApiStatsDayService service;
private final ApiStatsUIMapper mapper;
private final ApiStatsExcelExportService excelExportService;
private final ObpGwMetricJpaDAO apiNameDao;
@GetMapping(value = "/onl/kjb/statistics/apiStatsDayMan.view")
public String view() {
@@ -66,9 +72,38 @@ public class ApiStatsDayController {
@PostMapping(value = "/onl/kjb/statistics/apiStatsDayMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
fillApiDesc(page.getContent());
return ResponseEntity.ok(new GridResponse<>(page));
}
/**
* 요약 통계 행의 apiName(=API ID)으로 TSEAIHE01 을 조회하여 API 명(EAISVCDESC)을 채운다.
* 매칭되는 항목이 없으면 공란으로 둔다.
*/
private void fillApiDesc(List<ApiStatsUI> rows) {
if (rows == null || rows.isEmpty()) {
return;
}
Set<String> apiIds = rows.stream()
.map(ApiStatsUI::getApiName)
.filter(id -> id != null && !id.isEmpty())
.collect(Collectors.toSet());
if (apiIds.isEmpty()) {
return;
}
// API_STATS_DAY 와 동일한 APIGW 스키마에서 조회
DataSourceContextHolder.setDataSourceType(
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
Map<String, String> nameMap = apiNameDao.selectApiNames(apiIds);
for (ApiStatsUI row : rows) {
row.setApiDesc(nameMap.get(row.getApiName()));
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsDayMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -4,6 +4,8 @@ import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@@ -18,7 +20,10 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsHour;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsHourService;
import com.eactive.ext.kjb.statistics.mapping.ApiStatsUIMapper;
@@ -38,6 +43,7 @@ public class ApiStatsHourController {
private final ApiStatsHourService service;
private final ApiStatsUIMapper mapper;
private final ApiStatsExcelExportService excelExportService;
private final ObpGwMetricJpaDAO apiNameDao;
@GetMapping(value = "/onl/kjb/statistics/apiStatsHourMan.view")
public String view() {
@@ -66,9 +72,38 @@ public class ApiStatsHourController {
@PostMapping(value = "/onl/kjb/statistics/apiStatsHourMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
fillApiDesc(page.getContent());
return ResponseEntity.ok(new GridResponse<>(page));
}
/**
* 요약 통계 행의 apiName(=API ID)으로 TSEAIHE01 을 조회하여 API 명(EAISVCDESC)을 채운다.
* 매칭되는 항목이 없으면 공란으로 둔다.
*/
private void fillApiDesc(List<ApiStatsUI> rows) {
if (rows == null || rows.isEmpty()) {
return;
}
Set<String> apiIds = rows.stream()
.map(ApiStatsUI::getApiName)
.filter(id -> id != null && !id.isEmpty())
.collect(Collectors.toSet());
if (apiIds.isEmpty()) {
return;
}
// API_STATS_HOUR 와 동일한 APIGW 스키마에서 조회
DataSourceContextHolder.setDataSourceType(
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
Map<String, String> nameMap = apiNameDao.selectApiNames(apiIds);
for (ApiStatsUI row : rows) {
row.setApiDesc(nameMap.get(row.getApiName()));
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsHourMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -4,6 +4,8 @@ import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@@ -18,7 +20,10 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMinute;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMinuteService;
import com.eactive.ext.kjb.statistics.mapping.ApiStatsUIMapper;
@@ -38,6 +43,7 @@ public class ApiStatsMinuteController {
private final ApiStatsMinuteService service;
private final ApiStatsUIMapper mapper;
private final ApiStatsExcelExportService excelExportService;
private final ObpGwMetricJpaDAO apiNameDao;
@GetMapping(value = "/onl/kjb/statistics/apiStatsMinuteMan.view")
public String view() {
@@ -66,9 +72,38 @@ public class ApiStatsMinuteController {
@PostMapping(value = "/onl/kjb/statistics/apiStatsMinuteMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
fillApiDesc(page.getContent());
return ResponseEntity.ok(new GridResponse<>(page));
}
/**
* 요약 통계 행의 apiName(=API ID)으로 TSEAIHE01 을 조회하여 API 명(EAISVCDESC)을 채운다.
* 매칭되는 항목이 없으면 공란으로 둔다.
*/
private void fillApiDesc(List<ApiStatsUI> rows) {
if (rows == null || rows.isEmpty()) {
return;
}
Set<String> apiIds = rows.stream()
.map(ApiStatsUI::getApiName)
.filter(id -> id != null && !id.isEmpty())
.collect(Collectors.toSet());
if (apiIds.isEmpty()) {
return;
}
// API_STATS_MINUTE 와 동일한 APIGW 스키마에서 조회
DataSourceContextHolder.setDataSourceType(
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
Map<String, String> nameMap = apiNameDao.selectApiNames(apiIds);
for (ApiStatsUI row : rows) {
row.setApiDesc(nameMap.get(row.getApiName()));
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMinuteMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -4,6 +4,8 @@ import java.io.IOException;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@@ -18,7 +20,10 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMonth;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsMonthService;
import com.eactive.ext.kjb.statistics.mapping.ApiStatsUIMapper;
@@ -38,6 +43,7 @@ public class ApiStatsMonthController {
private final ApiStatsMonthService service;
private final ApiStatsUIMapper mapper;
private final ApiStatsExcelExportService excelExportService;
private final ObpGwMetricJpaDAO apiNameDao;
@GetMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.view")
public String view() {
@@ -66,9 +72,38 @@ public class ApiStatsMonthController {
@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
fillApiDesc(page.getContent());
return ResponseEntity.ok(new GridResponse<>(page));
}
/**
* 요약 통계 행의 apiName(=API ID)으로 TSEAIHE01 을 조회하여 API 명(EAISVCDESC)을 채운다.
* 매칭되는 항목이 없으면 공란으로 둔다.
*/
private void fillApiDesc(List<ApiStatsUI> rows) {
if (rows == null || rows.isEmpty()) {
return;
}
Set<String> apiIds = rows.stream()
.map(ApiStatsUI::getApiName)
.filter(id -> id != null && !id.isEmpty())
.collect(Collectors.toSet());
if (apiIds.isEmpty()) {
return;
}
// API_STATS_MONTH 와 동일한 APIGW 스키마에서 조회
DataSourceContextHolder.setDataSourceType(
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
Map<String, String> nameMap = apiNameDao.selectApiNames(apiIds);
for (ApiStatsUI row : rows) {
row.setApiDesc(nameMap.get(row.getApiName()));
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsMonthMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -3,6 +3,8 @@ package com.eactive.ext.kjb.statistics;
import java.io.IOException;
import java.time.Year;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@@ -17,7 +19,10 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
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.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsYear;
import com.eactive.eai.rms.data.entity.onl.kjb.statistics.ApiStatsYearService;
import com.eactive.ext.kjb.statistics.mapping.ApiStatsUIMapper;
@@ -37,6 +42,7 @@ public class ApiStatsYearController {
private final ApiStatsYearService service;
private final ApiStatsUIMapper mapper;
private final ApiStatsExcelExportService excelExportService;
private final ObpGwMetricJpaDAO apiNameDao;
@GetMapping(value = "/onl/kjb/statistics/apiStatsYearMan.view")
public String view() {
@@ -65,9 +71,38 @@ public class ApiStatsYearController {
@PostMapping(value = "/onl/kjb/statistics/apiStatsYearMan.json", params = "cmd=LIST_SUMMARY")
public ResponseEntity<GridResponse<ApiStatsUI>> selectSummaryList(ApiStatsSearch search, Pageable pageable) {
Page<ApiStatsUI> page = service.selectSummaryList(search, pageable);
fillApiDesc(page.getContent());
return ResponseEntity.ok(new GridResponse<>(page));
}
/**
* 요약 통계 행의 apiName(=API ID)으로 TSEAIHE01 을 조회하여 API 명(EAISVCDESC)을 채운다.
* 매칭되는 항목이 없으면 공란으로 둔다.
*/
private void fillApiDesc(List<ApiStatsUI> rows) {
if (rows == null || rows.isEmpty()) {
return;
}
Set<String> apiIds = rows.stream()
.map(ApiStatsUI::getApiName)
.filter(id -> id != null && !id.isEmpty())
.collect(Collectors.toSet());
if (apiIds.isEmpty()) {
return;
}
// API_STATS_YEAR 와 동일한 APIGW 스키마에서 조회
DataSourceContextHolder.setDataSourceType(
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
Map<String, String> nameMap = apiNameDao.selectApiNames(apiIds);
for (ApiStatsUI row : rows) {
row.setApiDesc(nameMap.get(row.getApiName()));
}
}
@PostMapping(value = "/onl/kjb/statistics/apiStatsYearMan.json", params = "cmd=EXCEL_EXPORT")
public void exportToExcel(ApiStatsSearch search, HttpServletResponse response) throws IOException {
log.info("Excel export started - search: {}", search);
@@ -11,6 +11,7 @@ import lombok.Data;
public class ApiStatsUI {
private String statTime;
private String apiName;
private String apiDesc;
private String gwInstanceId;
private String bizDivCode;
private String clientId;