Merge branch 'jenkins_with_weblogic' of http://192.168.240.178:18080/eapim/eapim-admin.git into jenkins_with_weblogic
This commit is contained in:
@@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
@@ -33,6 +34,16 @@ public class GlobalExceptionController {
|
||||
.map(SQLException::getMessage)
|
||||
.orElse("");
|
||||
errMsg = errMsg + "중복 KEY 에러발생.\n자세한 사항은 관리자에게 문의바랍니다. ";
|
||||
} else if (e instanceof DataIntegrityViolationException) {
|
||||
errMsg = "입력값이 올바르지 않습니다. 필수 항목을 확인해주세요.";
|
||||
} else if (e instanceof DataAccessException) {
|
||||
errMsg = "데이터베이스 처리 중 오류가 발생했습니다.";
|
||||
} else if (e instanceof SQLException) {
|
||||
errMsg = "데이터베이스 처리 중 오류가 발생했습니다.";
|
||||
}
|
||||
|
||||
if (errMsg != null && (errMsg.contains("NestedSQLException") || errMsg.contains("nested exception"))) {
|
||||
errMsg = "데이터베이스 처리 중 오류가 발생했습니다.";
|
||||
}
|
||||
|
||||
if (request.getServletPath().endsWith(".json")) {
|
||||
@@ -46,20 +57,21 @@ public class GlobalExceptionController {
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
public ModelAndView handleBizException(Exception e, HttpServletRequest request, HttpServletResponse response) {
|
||||
logger.error("GlobalExceptionController] handleBizException ", e);
|
||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
|
||||
if (request.getServletPath().endsWith(".json")) {
|
||||
HashMap resultMap = new HashMap();
|
||||
resultMap.put("status", "fail");
|
||||
resultMap.put("errorMsg", e.getMessage());
|
||||
ModelAndView modelAndView = new ModelAndView("jsonView", resultMap);
|
||||
return modelAndView;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// 26.02.10 - 웹취약점 관련(시스템 운영정보 노출, Exception 과 보다 먼저 처리되어 필요성이 없는듯하여 주석으로 삭제 처리
|
||||
// @ExceptionHandler(RuntimeException.class)
|
||||
// public ModelAndView handleBizException(Exception e, HttpServletRequest request, HttpServletResponse response) {
|
||||
// logger.error("GlobalExceptionController] handleBizException ", e);
|
||||
// response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||
//
|
||||
// if (request.getServletPath().endsWith(".json")) {
|
||||
// HashMap resultMap = new HashMap();
|
||||
// resultMap.put("status", "fail");
|
||||
// resultMap.put("errorMsg", e.getMessage());
|
||||
// ModelAndView modelAndView = new ModelAndView("jsonView", resultMap);
|
||||
// return modelAndView;
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -795,7 +795,7 @@ public class MainController implements InterceptorSkipController {
|
||||
|
||||
// 3. 비밀번호 체크
|
||||
if (!userInfo.getPassword().equals(Seed.encrypt(resetPassword))
|
||||
&& !userInfo.getUserid().equals(resetUserId)) {
|
||||
|| !userInfo.getUserid().equals(resetUserId)) {
|
||||
UserAccessLogger.log(request, LOG_CATEGORY_LOGIN, "F",
|
||||
localeMessage
|
||||
.getString("login.pwdmismatch5"));
|
||||
|
||||
@@ -2,6 +2,9 @@ package com.eactive.eai.rms.data.entity.onl.apim.obp;
|
||||
|
||||
import com.eactive.apim.portal.obp.entity.ObpGwMetric;
|
||||
import com.eactive.apim.portal.obp.repository.ObpGwMetricRepository;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -50,6 +53,24 @@ public class ObpGwMetricService {
|
||||
return repository.findByTimesliceGreaterThanEqual(timeslice);
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 시간대 이후의 GwMetric 데이터 조회 (row 수 제한)
|
||||
*
|
||||
* @param timeslice 조회 시작 시간대
|
||||
* @param limit 최대 조회 건수 (0이면 무제한)
|
||||
* @return 조회된 지표 목록 (timeslice ASC 정렬)
|
||||
*/
|
||||
public List<ObpGwMetric> findByTimesliceGreaterThanEqual(LocalDateTime timeslice, int limit) {
|
||||
if (limit <= 0) {
|
||||
// 무제한 조회 (기존 동작 유지)
|
||||
return repository.findByTimesliceGreaterThanEqual(timeslice);
|
||||
} else {
|
||||
// 제한적 조회 (timeslice ASC 정렬 + limit)
|
||||
Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Order.asc("timeslice")));
|
||||
return repository.findByTimesliceGreaterThanEqual(timeslice, pageable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 엔티티 저장 (INSERT 또는 UPDATE)
|
||||
*/
|
||||
|
||||
@@ -118,21 +118,23 @@ public class EAILogRepositoryImpl implements EAILogRepository {
|
||||
.where(qeaiLog.id.logprcssserno.eq(eaiLogSearch.getSearchLogPrcssSerno()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchStartTime())) {
|
||||
query
|
||||
|
||||
boolean hasSvcSerno = StringUtils.isNotBlank(eaiLogSearch.getSearchEaiSvcSerno());
|
||||
|
||||
if (hasSvcSerno) {
|
||||
query.where(qeaiLog.id.eaisvcserno.contains(eaiLogSearch.getSearchEaiSvcSerno()));
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchStartTime())) {
|
||||
query
|
||||
.where(qeaiLog.id.msgdpstyms
|
||||
.between(eaiLogSearch.getSearchStartTime(), eaiLogSearch.getSearchEndTime()));
|
||||
.between(eaiLogSearch.getSearchStartTime(), eaiLogSearch.getSearchEndTime()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchEaiBzwkDstcd())) {
|
||||
query.where(qeaiLog.id.eaibzwkdstcd.eq(eaiLogSearch.getSearchEaiBzwkDstcd()));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchEaiSvcSerno())) {
|
||||
query.where(qeaiLog.id.eaisvcserno.contains(eaiLogSearch.getSearchEaiSvcSerno()));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(eaiLogSearch.getSearchEaiSvcName())) {
|
||||
query.where(qeaiLog.eaisvcname.containsIgnoreCase(eaiLogSearch.getSearchEaiSvcName()));
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ import com.eactive.ext.kjb.common.KjbPropertyHolder;
|
||||
import com.eactive.ext.kjb.common.KjbUmsException;
|
||||
import com.eactive.ext.kjb.ums.KjbUmsService;
|
||||
import com.eactive.ext.kjb.ums.UmsBizWorkCode;
|
||||
import com.eactive.ext.kjb.ums.gson.IUmsGsonObject;
|
||||
import com.eactive.ext.kjb.ums.gson.GsonUtil;
|
||||
import com.eactive.ext.kjb.ums.gson.VerifyPhoneUmsTemplate;
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -121,8 +122,7 @@ public class SmsAuthService {
|
||||
String guid = String.format("EAPIM_EMS-%s",
|
||||
DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now()));
|
||||
|
||||
IUmsGsonObject content = null;
|
||||
content = VerifyPhoneUmsTemplate.builder().authNumber(authCode).build();
|
||||
JsonObject content = GsonUtil.toJsonObject(VerifyPhoneUmsTemplate.builder().authNumber(authCode).build());
|
||||
|
||||
getUmsService().sendKakaoAlimTalk(guid, UmsBizWorkCode.VERIFY_PHONE, cleanedPhone, content);
|
||||
log.info("SMS 인증번호 발송 완료 - guid: {}, phone: {}****{}",
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
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 엔드포인트용)
|
||||
*
|
||||
* <p>예시 출력 형식에 맞춤:</p>
|
||||
* <pre>
|
||||
* {
|
||||
* "apiId": "1ba56b82-a9c9-41e2-b3ab-ff9377667d56",
|
||||
* "apiName": "[해외송금] 가상계좌 입금실패 정보조회",
|
||||
* "apiRoutingUri": "/api/obs/remittance/remittancefail*",
|
||||
* "httpMethod": "POST",
|
||||
* "orgId": "ORG001",
|
||||
* "partnerCode": "000008-01",
|
||||
* "appId": "APP001",
|
||||
* "appKey": "l7xx2fd7efc523794be5a1b126873a5de613",
|
||||
* "requestUri": "-1",
|
||||
* "timeslice": "2025-12-02T03:00:00.000+0000",
|
||||
* "attemptedCount": 3,
|
||||
* "completedCount": 3
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@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("httpMethod")
|
||||
private String httpMethod;
|
||||
|
||||
@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;
|
||||
|
||||
|
||||
// AS-IS 호환을 위한 필드 (null 값으로 리턴)
|
||||
@SerializedName("clusterHostname")
|
||||
private String clusterHostname = null;
|
||||
|
||||
@SerializedName("apiDatabaseId")
|
||||
private Integer apiDatabaseId = null;
|
||||
|
||||
@SerializedName("unauthorizedCount")
|
||||
private Integer authorizedCount = null;
|
||||
|
||||
@SerializedName("backMinTime")
|
||||
private Integer backMinTime = null;
|
||||
|
||||
@SerializedName("backMaxTime")
|
||||
private Integer backMaxTime = null;
|
||||
|
||||
@SerializedName("backSumTime")
|
||||
private Integer backSumTime = null;
|
||||
|
||||
@SerializedName("frontMinTime")
|
||||
private Integer frontMinTime = null;
|
||||
|
||||
@SerializedName("frontMaxTime")
|
||||
private Integer frontMaxTime = null;
|
||||
|
||||
@SerializedName("frontSumTime")
|
||||
private Integer frontSumTime = null;
|
||||
|
||||
|
||||
/**
|
||||
* 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.setHttpMethod(entity.getMethod());
|
||||
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());
|
||||
|
||||
|
||||
// 260224 - AS-IS 개발자포탈에서 쓰이던 ID 필드 값 삭제(OBP 디비 필드 형식과 맞지 않음)
|
||||
dto.setOrgId(null);
|
||||
dto.setAppId(null);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -55,12 +55,12 @@ public class ObpGwMetricController extends BaseRestController {
|
||||
produces = JSON_CONTENT_TYPE
|
||||
)
|
||||
@ResponseBody
|
||||
public String getGwMetricsAfterTimesliceV2(
|
||||
public String getGwMetricsAfterTimeslice(
|
||||
@PathVariable("timeslice") String timeslice,
|
||||
@PathVariable("providerCode") String providerCode,
|
||||
@RequestParam(value = "pretty", required = false) Boolean pretty) {
|
||||
|
||||
log.debug("GwMetric after-timeslice 조회 요청 (v2): timeslice={}, providerCode={}, pretty={}",
|
||||
log.debug("GwMetric after-timeslice 조회 요청: timeslice={}, providerCode={}, pretty={}",
|
||||
timeslice, providerCode, pretty);
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ObpGwMetricController extends BaseRestController {
|
||||
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING));
|
||||
|
||||
// 5. 데이터 조회
|
||||
List<ObpGwMetricAfterDTO> metrics = obpGwMetricManService.findByTimesliceAfter(timesliceHour);
|
||||
List<ObpGwMetricDTO> metrics = obpGwMetricManService.findByTimesliceAfter(timesliceHour);
|
||||
|
||||
// 6. JSON 변환
|
||||
String json = toJson(metrics, pretty);
|
||||
@@ -104,90 +104,4 @@ public class ObpGwMetricController extends BaseRestController {
|
||||
throw new BizException("Failed to retrieve metrics: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 시간대의 GwMetric 데이터 조회
|
||||
*
|
||||
* @param datetime 조회 시간대 (형식: yyyy-MM-dd_HH:mm:ss)
|
||||
* @param pretty true면 JSON 들여쓰기 적용
|
||||
* @return JSON Array
|
||||
*/
|
||||
@RequestMapping(
|
||||
value = "/kjb/gw-metrics/{datetime}.json",
|
||||
produces = JSON_CONTENT_TYPE
|
||||
)
|
||||
@ResponseBody
|
||||
public String getGwMetrics(
|
||||
@PathVariable("datetime") String datetime,
|
||||
@RequestParam(value = "pretty", required = false) Boolean pretty) {
|
||||
log.debug("GwMetric 조회 요청: datetime={}, pretty={}", datetime, pretty);
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
// Path 파라미터 파싱
|
||||
LocalDateTime targetTime = LocalDateTime.parse(datetime, PATH_FORMATTER);
|
||||
LocalDateTime timeslice = targetTime.withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
// 조회
|
||||
List<ObpGwMetricDTO> metrics = obpGwMetricManService.findByTimeslice(timeslice);
|
||||
|
||||
// JSON 변환 (GSON)
|
||||
String json = toJson(metrics, pretty);
|
||||
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
log.info("GwMetric 조회 완료: datetime={}, count={}, size={}, elapsed={}ms",
|
||||
datetime, metrics.size(), getFormattedJsonSize(json), elapsed);
|
||||
|
||||
return json;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("GwMetric 조회 실패: datetime={}", datetime, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 시간대 이후의 GwMetric 데이터 조회
|
||||
*
|
||||
* @param datetime 조회 시작 시간대 (형식: yyyy-MM-dd_HH:mm:ss)
|
||||
* @param pretty true면 JSON 들여쓰기 적용
|
||||
* @return JSON Array (해당 시간대 이후의 모든 지표)
|
||||
* @deprecated Use {@link #getGwMetricsAfterTimesliceV2(String, String, Boolean)} instead.
|
||||
* Migrate to /api/metrics/afterTimeslice/{timeslice}/{providerCode}
|
||||
* Will be removed in next major version.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequestMapping(
|
||||
value = "/kjb/gw-metrics/after-timeslice/{datetime}.json",
|
||||
produces = JSON_CONTENT_TYPE
|
||||
)
|
||||
@ResponseBody
|
||||
public String getGwMetricsAfterTimeslice(
|
||||
@PathVariable("datetime") String datetime,
|
||||
@RequestParam(value = "pretty", required = false) Boolean pretty) {
|
||||
log.debug("GwMetric after-timeslice 조회 요청: datetime={}, pretty={}", datetime, pretty);
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
// Path 파라미터 파싱
|
||||
LocalDateTime targetTime = LocalDateTime.parse(datetime, PATH_FORMATTER);
|
||||
LocalDateTime timeslice = targetTime.withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
// 조회
|
||||
List<ObpGwMetricAfterDTO> metrics = obpGwMetricManService.findByTimesliceAfter(timeslice);
|
||||
|
||||
// JSON 변환 (GSON)
|
||||
String json = toJson(metrics, pretty);
|
||||
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
log.info("GwMetric after-timeslice 조회 완료: datetime={}, count={}, size={}, elapsed={}ms",
|
||||
datetime, metrics.size(), getFormattedJsonSize(json), elapsed);
|
||||
|
||||
return json;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("GwMetric after-timeslice 조회 실패: datetime={}", datetime, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,32 +8,61 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* ObpGwMetric JSON 응답 DTO
|
||||
* Entity 주석에 명시된 JSON Key 사용
|
||||
* ObpGwMetric JSON 응답 DTO (after-timeslice 엔드포인트용)
|
||||
*
|
||||
* <p>예시 출력 형식에 맞춤:</p>
|
||||
* <pre>
|
||||
* {
|
||||
* "apiId": "1ba56b82-a9c9-41e2-b3ab-ff9377667d56",
|
||||
* "apiName": "[해외송금] 가상계좌 입금실패 정보조회",
|
||||
* "apiRoutingUri": "/api/obs/remittance/remittancefail*",
|
||||
* "httpMethod": "POST",
|
||||
* "orgId": "ORG001",
|
||||
* "partnerCode": "000008-01",
|
||||
* "appId": "APP001",
|
||||
* "appKey": "l7xx2fd7efc523794be5a1b126873a5de613",
|
||||
* "requestUri": "-1",
|
||||
* "timeslice": "2025-12-02T03:00:00.000+0000",
|
||||
* "attemptedCount": 3,
|
||||
* "completedCount": 3
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@Data
|
||||
public class ObpGwMetricDTO {
|
||||
|
||||
private static final DateTimeFormatter ISO8601_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'+0000'");
|
||||
private static final DateTimeFormatter ISO8601_MILLIS_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'+0900'");
|
||||
|
||||
@SerializedName("appKey")
|
||||
private String clientId;
|
||||
|
||||
@SerializedName("clusterHostname")
|
||||
private String hostname;
|
||||
|
||||
@SerializedName("timeslice")
|
||||
private String timeslice;
|
||||
@SerializedName("apiId")
|
||||
private String apiId;
|
||||
|
||||
@SerializedName("apiName")
|
||||
private String apiName;
|
||||
|
||||
@SerializedName("apiRoutingUri")
|
||||
private String uri;
|
||||
private String apiRoutingUri;
|
||||
|
||||
@SerializedName("httpMethod")
|
||||
private String method;
|
||||
private String httpMethod;
|
||||
|
||||
@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;
|
||||
@@ -41,62 +70,68 @@ public class ObpGwMetricDTO {
|
||||
@SerializedName("completedCount")
|
||||
private Long completedCount;
|
||||
|
||||
// EAPIM ID
|
||||
@SerializedName("apiIdByEapim")
|
||||
private String apiId;
|
||||
|
||||
@SerializedName("appIdByEapim")
|
||||
private String appId;
|
||||
// AS-IS 호환을 위한 필드 (null 값으로 리턴)
|
||||
@SerializedName("clusterHostname")
|
||||
private String clusterHostname = null;
|
||||
|
||||
@SerializedName("orgIdByEapim")
|
||||
private String orgId;
|
||||
@SerializedName("apiDatabaseId")
|
||||
private Integer apiDatabaseId = null;
|
||||
|
||||
// AS-IS 호환용 필드
|
||||
@SerializedName("appId")
|
||||
private String appIdByCaPortal;
|
||||
@SerializedName("unauthorizedCount")
|
||||
private Integer authorizedCount = null;
|
||||
|
||||
@SerializedName("portalOrgId")
|
||||
private String orgIdByCaPortal;
|
||||
@SerializedName("backMinTime")
|
||||
private Integer backMinTime = null;
|
||||
|
||||
@SerializedName("portalApiId")
|
||||
private String apiIdByCaPortal;
|
||||
@SerializedName("backMaxTime")
|
||||
private Integer backMaxTime = null;
|
||||
|
||||
@SerializedName("partnerCode")
|
||||
private String partnerCode;
|
||||
@SerializedName("backSumTime")
|
||||
private Integer backSumTime = null;
|
||||
|
||||
@SerializedName("frontMinTime")
|
||||
private Integer frontMinTime = null;
|
||||
|
||||
@SerializedName("frontMaxTime")
|
||||
private Integer frontMaxTime = null;
|
||||
|
||||
@SerializedName("frontSumTime")
|
||||
private Integer frontSumTime = null;
|
||||
|
||||
@SerializedName("apiId")
|
||||
private String apiIdByCa;
|
||||
|
||||
/**
|
||||
* Entity → DTO 변환
|
||||
*/
|
||||
public static ObpGwMetricDTO from(ObpGwMetric entity) {
|
||||
ObpGwMetricDTO dto = new ObpGwMetricDTO();
|
||||
dto.setClientId(entity.getClientId());
|
||||
dto.setHostname(entity.getHostname());
|
||||
dto.setTimeslice(formatTimeslice(entity.getTimeslice()));
|
||||
dto.setApiId(entity.getApiId());
|
||||
dto.setApiName(entity.getApiName());
|
||||
dto.setUri(entity.getUri());
|
||||
dto.setMethod(entity.getMethod());
|
||||
dto.setApiRoutingUri(entity.getUri());
|
||||
dto.setHttpMethod(entity.getMethod());
|
||||
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());
|
||||
dto.setApiId(entity.getApiId());
|
||||
dto.setAppId(entity.getAppId());
|
||||
dto.setOrgId(entity.getOrgId());
|
||||
dto.setAppIdByCaPortal(entity.getAppIdByCaPortal());
|
||||
dto.setOrgIdByCaPortal(entity.getOrgIdByCaPortal());
|
||||
dto.setApiIdByCaPortal(entity.getApiIdByCaPortal());
|
||||
dto.setPartnerCode(entity.getPartnerCode());
|
||||
dto.setApiIdByCa(entity.getApiIdByCa());
|
||||
|
||||
|
||||
// 260224 - AS-IS 개발자포탈에서 쓰이던 ID 필드 값 삭제(OBP 디비 필드 형식과 맞지 않음)
|
||||
dto.setOrgId(null);
|
||||
dto.setAppId(null);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* timeslice를 ISO8601 형식 + UTC 시간대로 변환
|
||||
* 예: 2025-12-02T01:00:00+0000
|
||||
* 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_FORMATTER);
|
||||
return timeslice.format(ISO8601_MILLIS_FORMATTER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.eactive.eai.rms.common.util.CommonUtil;
|
||||
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO;
|
||||
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricService;
|
||||
import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricVO;
|
||||
import com.eactive.ext.kjb.common.KjbPropertyHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
@@ -311,30 +312,32 @@ public class ObpGwMetricManService extends BaseService {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 시간대의 GwMetric 데이터 조회 (REST API용)
|
||||
*/
|
||||
public List<ObpGwMetricDTO> findByTimeslice(LocalDateTime timeslice) {
|
||||
DataSourceContextHolder.setDataSourceType(
|
||||
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING));
|
||||
|
||||
List<ObpGwMetric> entities = obpGwMetricService.findByTimeslice(timeslice);
|
||||
return entities.stream()
|
||||
.map(ObpGwMetricDTO::from)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 시간대 이후의 GwMetric 데이터 조회 (REST API용)
|
||||
* after-timeslice 엔드포인트에서 사용
|
||||
*
|
||||
* <p>조회 범위 제한:</p>
|
||||
* <ul>
|
||||
* <li>pageSize 값을 KjbProperty.apiGwMetricPageSize에서 읽어옴 (기본값: 10000)</li>
|
||||
* <li>0일 경우 무제한 조회</li>
|
||||
* <li>정렬: timeslice ASC (오래된 데이터부터 반환)</li>
|
||||
* </ul>
|
||||
*/
|
||||
public List<ObpGwMetricAfterDTO> findByTimesliceAfter(LocalDateTime timeslice) {
|
||||
public List<ObpGwMetricDTO> findByTimesliceAfter(LocalDateTime timeslice) {
|
||||
DataSourceContextHolder.setDataSourceType(
|
||||
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING));
|
||||
|
||||
List<ObpGwMetric> entities = obpGwMetricService.findByTimesliceGreaterThanEqual(timeslice);
|
||||
// KjbProperty에서 pageSize 읽기
|
||||
Integer pageSize = KjbPropertyHolder.get().getApiGwMetricPageSize();
|
||||
if (pageSize == null) {
|
||||
pageSize = 10000; // 기본값 (null 안전 처리)
|
||||
}
|
||||
|
||||
// Service 호출 (limit 적용)
|
||||
List<ObpGwMetric> entities = obpGwMetricService.findByTimesliceGreaterThanEqual(timeslice, pageSize);
|
||||
|
||||
return entities.stream()
|
||||
.map(ObpGwMetricAfterDTO::from)
|
||||
.map(ObpGwMetricDTO::from)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,11 @@ public class PortalUserManService extends BaseService {
|
||||
if (StringUtils.isNotBlank(portalUserUI.getOrgId())) {
|
||||
PortalOrg portalOrg = portalOrgService.getById(portalUserUI.getOrgId());
|
||||
portalUser.setPortalOrg(portalOrg);
|
||||
} else {
|
||||
// 개인사용자이면서 법인을 "없음"으로 선택한 경우 ORG_ID 삭제
|
||||
if (portalUserUI.getRoleCode() == PortalUserEnums.RoleCode.ROLE_USER) {
|
||||
portalUser.setPortalOrg(null);
|
||||
}
|
||||
}
|
||||
|
||||
portalUserService.save(portalUser);
|
||||
|
||||
+30
-41
@@ -404,7 +404,7 @@ public class LayoutSyncController extends OnlBaseAnnotationController implements
|
||||
String resultS = null;
|
||||
ServletInputStream sis = null;
|
||||
|
||||
HashMap<String, String> param = new HashMap<String, String>();
|
||||
HashMap<String, String> param = new HashMap<>();
|
||||
String recvTime = DateUtil.getDateTime("yyyyMMddHHmmssSS").substring(0, 16);
|
||||
|
||||
// 초기화
|
||||
@@ -431,43 +431,33 @@ public class LayoutSyncController extends OnlBaseAnnotationController implements
|
||||
byte[] arg = new byte[request.getContentLength()];
|
||||
int resultSet = 0;
|
||||
int total = 0;
|
||||
try {
|
||||
resultSet = sis.readLine(arg, 0, arg.length);
|
||||
while(resultSet != -1) {
|
||||
total += resultSet;
|
||||
resultSet = sis.readLine(arg, total, 1024);
|
||||
}
|
||||
|
||||
String xmlContent = null;
|
||||
try {
|
||||
resultSet = sis.readLine(arg, 0, arg.length);
|
||||
while (resultSet != -1) {
|
||||
total += resultSet;
|
||||
resultSet = sis.readLine(arg, total, 1024);
|
||||
}
|
||||
|
||||
// ===== 인코딩 확인 로그 시작 =====
|
||||
logger.info("========== 인코딩 디버깅 정보 ==========");
|
||||
logger.info("request.getCharacterEncoding(): " + request.getCharacterEncoding());
|
||||
logger.info("request.getContentType(): " + request.getContentType());
|
||||
logger.info("Content Length: " + arg.length + " bytes");
|
||||
xmlContent = new String(arg, "EUC-KR");
|
||||
// ===== 인코딩 확인 로그 시작 =====
|
||||
logger.info("========== 인코딩 디버깅 정보 ==========");
|
||||
// 다양한 인코딩으로 읽어보기
|
||||
logger.info("request.getCharacterEncoding(): {}", request.getCharacterEncoding());
|
||||
logger.info("request.getContentType(): {}", request.getContentType());
|
||||
logger.info("Content Length: {} bytes", arg.length);
|
||||
logger.info("EUC-KR 전체 내용:\n{}", xmlContent);
|
||||
logger.info("========================================");
|
||||
// ===== 인코딩 확인 로그 끝 =====
|
||||
param.put("recvData", xmlContent);
|
||||
} catch (Exception e) {
|
||||
logger.error("MessageSync.err - don't read the XML File", e);
|
||||
param.put("recvData", "");
|
||||
}
|
||||
|
||||
// 다양한 인코딩으로 읽어보기
|
||||
String asDefaultEncoding = new String(arg);
|
||||
String asUtf8 = new String(arg, "UTF-8");
|
||||
String asEucKr = new String(arg, "EUC-KR");
|
||||
|
||||
logger.info("Default Encoding 전체 내용:\n" + asDefaultEncoding);
|
||||
logger.info("UTF-8 전체 내용:\n" + asUtf8);
|
||||
logger.info("EUC-KR 전체 내용:\n" + asEucKr);
|
||||
logger.info("========================================");
|
||||
// ===== 인코딩 확인 로그 끝 =====
|
||||
|
||||
param.put("recvData", new String(arg, "EUC-KR"));
|
||||
} catch(Exception e) {
|
||||
logger.error("MessageSync.err - don't read the XML File - " + new String(arg, "EUC-KR"), e);
|
||||
param.put("recvData", "");
|
||||
}
|
||||
|
||||
// byte[]로부터 XML 파싱 (BOM 제거) - EUC-KR로 읽기
|
||||
String xmlContent = new String(arg, "EUC-KR").trim();
|
||||
// BOM 제거 (UTF-8 BOM: EF BB BF)
|
||||
if (xmlContent.startsWith("\uFEFF")) {
|
||||
xmlContent = xmlContent.substring(1);
|
||||
}
|
||||
Document doc = builder.build(new ByteArrayInputStream(xmlContent.getBytes("EUC-KR")));
|
||||
// byte[]로부터 XML 파싱 - EUC-KR로 읽기
|
||||
Document doc = builder.build(new StringReader(xmlContent));
|
||||
|
||||
param.put("logPrcssSeqno", UUIDGenerator.getUUID());
|
||||
// xml 1.1
|
||||
@@ -485,9 +475,9 @@ public class LayoutSyncController extends OnlBaseAnnotationController implements
|
||||
param.put("recvAmndHMS", recvTime);
|
||||
|
||||
logger.info(layoutName + " command - [" + command +"]");
|
||||
HashMap<String, Object> returnMap = new HashMap<String,Object>();
|
||||
HashMap<String, Object> returnMap = new HashMap<>();
|
||||
if( command.equals("delete") ) {
|
||||
HashMap<String,Object> vo = new HashMap<String,Object>();
|
||||
HashMap<String,Object> vo = new HashMap<>();
|
||||
vo.put("loutName",layoutName);
|
||||
|
||||
service.deleteLayout(vo);
|
||||
@@ -513,10 +503,10 @@ public class LayoutSyncController extends OnlBaseAnnotationController implements
|
||||
// }
|
||||
|
||||
String layout = body.getChild("data").getText();
|
||||
logger.info(layoutName + " recv Data - [" + layout + "]");
|
||||
logger.info("{} recv Data - [{}]]", layoutName, layout);
|
||||
param.put("recvData", layout);
|
||||
|
||||
Document doc2 = builder.build(new ByteArrayInputStream(layout.getBytes()));
|
||||
Document doc2 = builder.build(new StringReader(layout));
|
||||
|
||||
HashMap<String,Object> vo = new HashMap<String,Object>();
|
||||
|
||||
@@ -601,7 +591,6 @@ public class LayoutSyncController extends OnlBaseAnnotationController implements
|
||||
|
||||
} catch( Exception e ) {
|
||||
logger.error("",e);
|
||||
logger.error("",e.getStackTrace()[0]);
|
||||
try {
|
||||
if( results != null ) {
|
||||
if (e instanceof UseSystemException) {
|
||||
|
||||
+109
-2
@@ -4,6 +4,7 @@ import com.eactive.eai.common.EAITable;
|
||||
import com.eactive.eai.common.logger.HttpAdapterExtraLogVo;
|
||||
import com.eactive.eai.common.util.MessageUtil;
|
||||
import com.eactive.eai.data.entity.onl.adapter.AdapterGroup;
|
||||
import com.eactive.eai.data.entity.onl.server.EAIServer;
|
||||
import com.eactive.eai.rms.common.combo.ComboVo;
|
||||
import com.eactive.eai.rms.common.context.MonitoringContext;
|
||||
import com.eactive.eai.rms.common.logging.UserAccessLogger;
|
||||
@@ -12,10 +13,12 @@ import com.eactive.eai.rms.common.vo.GridResponse;
|
||||
import com.eactive.eai.rms.data.entity.onl.adapter.AdapterGroupService;
|
||||
import com.eactive.eai.rms.data.entity.onl.logger.EAILogDetailSearch;
|
||||
import com.eactive.eai.rms.data.entity.onl.logger.EAILogSearch;
|
||||
import com.eactive.eai.rms.data.entity.onl.server.EAIServerService;
|
||||
import com.eactive.eai.transformer.message.ISO8583MessageFactory;
|
||||
import com.eactive.eai.transformer.util.CommonLib;
|
||||
import com.eactive.eai.transformer.util.IConv;
|
||||
import com.eactive.eai.transformer.util.ISO8583DumpUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import com.solab.iso8583.IsoMessage;
|
||||
import org.apache.commons.io.HexDump;
|
||||
@@ -24,11 +27,20 @@ import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.ResourceAccessException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -44,15 +56,20 @@ public class DbTrackingController {
|
||||
private final DbTrackingService service;
|
||||
private final MonitoringContext monitoringContext;
|
||||
private final AdapterGroupService adapterGroupService;
|
||||
|
||||
private final EAIServerService eaiServerService;
|
||||
|
||||
private RestTemplate restTemplate = new RestTemplate();
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Autowired
|
||||
public DbTrackingController(DbTrackingService service,
|
||||
MonitoringContext monitoringContext,
|
||||
AdapterGroupService adapterGroupService) {
|
||||
AdapterGroupService adapterGroupService,
|
||||
EAIServerService eaiServerService) {
|
||||
this.service = service;
|
||||
this.monitoringContext = monitoringContext;
|
||||
this.adapterGroupService = adapterGroupService;
|
||||
this.eaiServerService = eaiServerService;
|
||||
}
|
||||
|
||||
@GetMapping(value = "/onl/transaction/tracking/trackingMan.view")
|
||||
@@ -538,5 +555,95 @@ public class DbTrackingController {
|
||||
|
||||
return new String(byteArrayOutputStream.toByteArray());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/onl/transaction/tracking/trackingMan.json", params = "cmd=DETAIL_PRETTY_VIEW")
|
||||
public ResponseEntity<?> selectList(@RequestParam Map<String, Object> paramMap) {
|
||||
|
||||
List<EAIServer> serverList = eaiServerService.selectEaiServerIpList();
|
||||
|
||||
if (serverList == null || serverList.isEmpty()) {
|
||||
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.body(Collections.singletonMap("error", "접속 가능한 서버 목록이 없습니다."));
|
||||
}
|
||||
|
||||
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
|
||||
factory.setConnectTimeout(2000);
|
||||
factory.setReadTimeout(5000);
|
||||
RestTemplate restTemplate = new RestTemplate(factory);
|
||||
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("intrefaceId", paramMap.get("intrefaceId"));
|
||||
requestBody.put("logProcessNo", paramMap.get("logProcessNo"));
|
||||
requestBody.put("bizData", paramMap.get("bizData"));
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
|
||||
|
||||
Map<String, Object> resultResponse = null;
|
||||
boolean isSuccess = false;
|
||||
String lastErrorMsg = "";
|
||||
|
||||
for(EAIServer server : serverList) {
|
||||
|
||||
String ip = server.getEaisevrip();
|
||||
String port = server.getSevrlsnportname();
|
||||
|
||||
if(ip == null || port == null) continue;
|
||||
|
||||
String targetUrl = "http://" + ip + ":" + port + "/PrettyPrint";
|
||||
|
||||
try {
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
targetUrl,
|
||||
HttpMethod.POST,
|
||||
entity,
|
||||
Map.class
|
||||
);
|
||||
|
||||
if(response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
|
||||
resultResponse = response.getBody();
|
||||
isSuccess = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} catch (ResourceAccessException e) {
|
||||
lastErrorMsg = "Network Error: " + e.getMessage();
|
||||
logger.debug("서버 접속 실패 : " + lastErrorMsg);
|
||||
continue;
|
||||
|
||||
} catch (HttpStatusCodeException e) {
|
||||
String errorBodyString = e.getResponseBodyAsString();
|
||||
logger.debug("서버 내부 에러 [" + targetUrl + "] : " + errorBodyString);
|
||||
|
||||
try {
|
||||
// 에러 문자열을 Map(JSON 객체)으로 변환 시도
|
||||
Map<String, Object> errorMap = objectMapper.readValue(errorBodyString, Map.class);
|
||||
return ResponseEntity.status(e.getStatusCode()).body(errorMap);
|
||||
} catch (Exception parseError) {
|
||||
// 일반 텍스트를 보냈다면 수동으로 Map 생성
|
||||
Map<String, Object> manualErrorMap = new HashMap<>();
|
||||
manualErrorMap.put("error", true);
|
||||
manualErrorMap.put("result", errorBodyString);
|
||||
return ResponseEntity.status(e.getStatusCode()).body(manualErrorMap);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isSuccess && resultResponse != null) {
|
||||
|
||||
return ResponseEntity.ok(resultResponse);
|
||||
} else {
|
||||
// 모든 서버 실패
|
||||
Map<String, Object> errorMap = new HashMap<>();
|
||||
errorMap.put("error", true);
|
||||
errorMap.put("result", "서버 연결 실패");
|
||||
// errorMap.put("result", "서버 연결 실패 (Last Error: " + lastErrorMsg + ")");
|
||||
logger.debug("서버 POST 요청 에러 : " + lastErrorMsg);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ public class DbTrackingService extends BaseService {
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).trim();
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user