diff --git a/WebContent/jsp/bap/admin/common/serverManDetail.jsp b/WebContent/jsp/bap/admin/common/serverManDetail.jsp index 7379911..3b0f8b2 100644 --- a/WebContent/jsp/bap/admin/common/serverManDetail.jsp +++ b/WebContent/jsp/bap/admin/common/serverManDetail.jsp @@ -24,7 +24,6 @@ function init(url){ dataType:"json", data:{cmd: 'LIST_INIT_COMBO'}, success:function(json){ - debugger; //new makeOptions("CODE","NAME").setObj($("select[name=flovrSevrName]")).setNoValueInclude(true).setNoValue(' ','전체').setData(json.serverRows).rendering(); new makeOptions("CODE","NAME").setObj($("select[name=flovrSevrName]")).setData(json.serverRows).rendering(); detail(url); diff --git a/WebContent/jsp/bap/admin/common/sysinfoMan.jsp b/WebContent/jsp/bap/admin/common/sysinfoMan.jsp index 8d8a422..c34f0a7 100644 --- a/WebContent/jsp/bap/admin/common/sysinfoMan.jsp +++ b/WebContent/jsp/bap/admin/common/sysinfoMan.jsp @@ -29,7 +29,7 @@ } $(document).ready(function() { -debugger; +//debugger; init( detail); $('#grid').jqGrid({ datatype:"json", diff --git a/WebContent/jsp/bap/admin/common/sysinfoManDetail.jsp b/WebContent/jsp/bap/admin/common/sysinfoManDetail.jsp index 3072f35..1d28265 100644 --- a/WebContent/jsp/bap/admin/common/sysinfoManDetail.jsp +++ b/WebContent/jsp/bap/admin/common/sysinfoManDetail.jsp @@ -35,7 +35,6 @@ success : function(json) { var data = json; var detail = json.detail; - debugger; // $("select[name=workGrpCd]").attr("disabled",true); // $("select[name=sndRcvKind]").attr("disabled",true); // $("select[name=adptrKind]").attr("disabled",true); diff --git a/WebContent/jsp/bap/admin/message/messageMetaManDetail.jsp b/WebContent/jsp/bap/admin/message/messageMetaManDetail.jsp index 7f168ab..0fd8d09 100644 --- a/WebContent/jsp/bap/admin/message/messageMetaManDetail.jsp +++ b/WebContent/jsp/bap/admin/message/messageMetaManDetail.jsp @@ -110,7 +110,7 @@ var name = $(this).attr("name"); var rowId = name.split("_")[2]; var rows = $('#grid').jqGrid('getGridParam','reccount'); - debugger; + //debugger; for ( var i = Number(rowId)+1 ; i <= rows; i ++){ var newVal = $('#grid').jqGrid('getCell',i,'MSGCLMNSEQ'); newVal = Number(newVal)-1; @@ -154,7 +154,7 @@ var name = $(this).attr("name"); var rowId = name.split("_")[2]; var rows = $('#grid').jqGrid('getGridParam','reccount'); - debugger; + //debugger; for ( var i = Number(rowId)+1 ; i <= rows; i ++){ var newVal = $('#grid').jqGrid('getCell',i,'MSGCLMNSEQ'); newVal = Number(newVal)-1; diff --git a/WebContent/jsp/bap/admin/schedule/holidayManDetail.jsp b/WebContent/jsp/bap/admin/schedule/holidayManDetail.jsp index f574beb..2d21504 100644 --- a/WebContent/jsp/bap/admin/schedule/holidayManDetail.jsp +++ b/WebContent/jsp/bap/admin/schedule/holidayManDetail.jsp @@ -44,7 +44,6 @@ $(document).ready(function() { var holdyYmd ="${param.holdyYmd}"; var holdyDstcd ="${param.holdyDstcd}"; var evntSchdrHoldyCtnt ="${param.evntSchdrHoldyCtnt}"; - debugger; if (holdyYmd != "" && holdyYmd !="null"){ isDetail = true; } diff --git a/WebContent/jsp/bap/admin/schedule/scheduleManDetail.jsp b/WebContent/jsp/bap/admin/schedule/scheduleManDetail.jsp index 7185407..9651be6 100644 --- a/WebContent/jsp/bap/admin/schedule/scheduleManDetail.jsp +++ b/WebContent/jsp/bap/admin/schedule/scheduleManDetail.jsp @@ -76,7 +76,7 @@ function getOgranFile(key){ $("select[name=bjobMsgDstcd],select[name=osidInstiDstcd]").empty(); new makeOptions("CODE","NAME").setObj($("select[name=osidInstiDstcd]")).setData(json.osidInstiDstcd).rendering(); new makeOptions("CODE","NAME").setObj($("select[name=bjobMsgDstcd]")).setData(json.bjobMsgDstcd).rendering(); - debugger; + //debugger; if ( !isDetail ){ getBjobPtrnDstcd(key); }else{ diff --git a/WebContent/jsp/bap/admin/work/interfaceManBatchFepDetail.jsp b/WebContent/jsp/bap/admin/work/interfaceManBatchFepDetail.jsp index 08098d1..fd1d199 100644 --- a/WebContent/jsp/bap/admin/work/interfaceManBatchFepDetail.jsp +++ b/WebContent/jsp/bap/admin/work/interfaceManBatchFepDetail.jsp @@ -51,7 +51,7 @@ $(function(){ $(document).ready(function() { var returnUrl = getReturnUrlForReturn(); - debugger; + //debugger; var key ="${param.infId}"; delFlag = "${param.delFlag}"; diff --git a/WebContent/jsp/bap/admin/work/messageProcManDetail.jsp b/WebContent/jsp/bap/admin/work/messageProcManDetail.jsp index 6205974..dd4453a 100644 --- a/WebContent/jsp/bap/admin/work/messageProcManDetail.jsp +++ b/WebContent/jsp/bap/admin/work/messageProcManDetail.jsp @@ -177,7 +177,7 @@ $(document).ready(function() { $("#btn_modify").click(function(){ - debugger; + //debugger; if (!isValid())return; if($("#grid tr#" + lastsel2).attr("editable") == 1){ //editable=1 means row in edit mode $("#grid").saveRow(lastsel2,false,"clientArray"); diff --git a/WebContent/jsp/bap/transaction/transactionTraceMan.jsp b/WebContent/jsp/bap/transaction/transactionTraceMan.jsp index 6625437..ec84bf7 100644 --- a/WebContent/jsp/bap/transaction/transactionTraceMan.jsp +++ b/WebContent/jsp/bap/transaction/transactionTraceMan.jsp @@ -92,7 +92,7 @@ url:url, data:postData, success:function(args){ - debugger; + //debugger; $("#grid").trigger("reloadGrid"); alert( args.result ); }, @@ -200,7 +200,7 @@ $(document).ready(function() { }, gridComplete: function(){ - debugger; + //debugger; var ids = $(this).getDataIDs(); for(var i=0;i':'<%= localeMessage.getString("adapterStat.close") %>'; var resultConfirm = confirm(replaceMsg("<%= localeMessage.getString("common.confirmMsg1") %>",msgStartStop,data["adapterGroupName"],data["adapterName"])); // // data["adapterGroupName"]+ " "+ data["adapterName"]+ "을\n\n"+ msgStartStop+ " 하시겠습니까?" diff --git a/WebContent/jsp/onl/admin/rule/layoutManDetail.jsp b/WebContent/jsp/onl/admin/rule/layoutManDetail.jsp index 8bcf3eb..4ab7166 100644 --- a/WebContent/jsp/onl/admin/rule/layoutManDetail.jsp +++ b/WebContent/jsp/onl/admin/rule/layoutManDetail.jsp @@ -375,10 +375,20 @@ url:url, data:postData, success:function(args){ - alert("<%=localeMessage.getString("common.saveMsg")%>"); if(isPop == "true"){ + alert("<%=localeMessage.getString("common.saveMsg")%> \n저장 후 변환정보 수정이 필수입니다. 변환정보를 확인하세요"); + const origin = window.location.origin; + + const layoutName = $("input[name='loutName']").val(); + + parent.postMessage({ + action: 'LAYOUT_SAVED_OPEN_TRANSFORM', + layoutPartName: '${param.layoutPartName}' + }, origin); + window.close(); } else { + alert("<%=localeMessage.getString("common.saveMsg")%>"); goNav(returnUrl); } }, diff --git a/WebContent/jsp/onl/admin/rule/transform2/transform2ManDetail.jsp b/WebContent/jsp/onl/admin/rule/transform2/transform2ManDetail.jsp index 577526e..08e7907 100644 --- a/WebContent/jsp/onl/admin/rule/transform2/transform2ManDetail.jsp +++ b/WebContent/jsp/onl/admin/rule/transform2/transform2ManDetail.jsp @@ -880,7 +880,7 @@ }); $("input[name=auto]").click(function(){ - debugger; + //debugger; jsPlumbInstance.deleteEveryConnection(); const sourceData = sourceGrid.getRowData(); diff --git a/WebContent/jsp/onl/admin/rule/transformManDetailPopup.jsp b/WebContent/jsp/onl/admin/rule/transformManDetailPopup.jsp index bb620e6..e0573e7 100644 --- a/WebContent/jsp/onl/admin/rule/transformManDetailPopup.jsp +++ b/WebContent/jsp/onl/admin/rule/transformManDetailPopup.jsp @@ -104,7 +104,7 @@ $(document).ready(function() { resizeJqGridWidth('grid','title','1000'); $("#btn_close").click(function(){ - debugger; + //debugger; window.close(); }); $("body").css("overflow-x","hidden"); diff --git a/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailyMan.jsp b/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailyMan.jsp index 7692acf..bade84d 100644 --- a/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailyMan.jsp +++ b/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailyMan.jsp @@ -154,7 +154,7 @@ function w2GridToExcelSubmit(url_excel,cmd,gridObj,formObject,fileName){ // var form="
"; var form=""; $.each(postData,function(_,obj){ - debugger; + //debugger; form +=""; }); form += "
"; diff --git a/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailySituation.jsp b/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailySituation.jsp index ec6c5ee..7c9c864 100644 --- a/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailySituation.jsp +++ b/WebContent/jsp/onl/statistics/eaisvcname/eaiSvcNameDailySituation.jsp @@ -140,7 +140,7 @@ function w2GridToExcelSubmit(url_excel,cmd,gridObj,formObject,fileName){ // var form="
"; var form=""; $.each(postData,function(_,obj){ - debugger; + //debugger; form +=""; }); form += "
"; diff --git a/WebContent/jsp/onl/transaction/apim/apiInterfaceManDetail.jsp b/WebContent/jsp/onl/transaction/apim/apiInterfaceManDetail.jsp index 4072679..f6ecc27 100644 --- a/WebContent/jsp/onl/transaction/apim/apiInterfaceManDetail.jsp +++ b/WebContent/jsp/onl/transaction/apim/apiInterfaceManDetail.jsp @@ -1153,19 +1153,46 @@ addLayoutBtnEvent('outboundErrResponse', '아웃바운드 오류', 'TGTE'); window.addEventListener('message', function(e) { + if (e.origin !== window.location.origin) return; + const popupMessage = e.data; - if('DELETE' == popupMessage.cmd){ - if('layout' == popupMessage.type){ - $('#'+popupMessage.layoutPartName).val(''); + if (!popupMessage) return; + + if ('DELETE' == popupMessage.cmd) { + if ('layout' == popupMessage.type) { + $('#' + popupMessage.layoutPartName).val(''); } - if('transform' == popupMessage.type){ + if ('transform' == popupMessage.type) { const partName = popupMessage.transformName.endsWith('REQ') ? '#requestTransform' : '#responseTransform'; $(partName).val(''); } transformSetStateChange(); + return; + } + + // 레이아웃 저장 후 변환 팝업 자동 실행 로직 + if (popupMessage.action === 'LAYOUT_SAVED_OPEN_TRANSFORM') { + + // 눈이 보이지않는 팝업창 popup창 닫기 + if ($('.ui-dialog-content').length > 0) { + $('.ui-dialog-content').dialog('close'); + } + + const part = popupMessage.layoutPartName || ""; + + setTimeout(function() { + if (part.includes('Request')) { + modifyTransform('request'); + } else if (part.includes('Response')) { + modifyTransform('response'); + } else if (part.includes('ErrResponse')) { + modifyTransform('errResponse'); + } + }, 300); } }); - + // modifyLayout('inboundRequestLayout', '인바운드 요청', 'CBSS') + $('#requestTransformButton').on("click", function(event) { modifyTransform('request'); }); @@ -1175,7 +1202,6 @@ $('#errResponseTransformButton').on("click", function(event) { modifyTransform('errResponse'); }); - // modifyLayout('inboundRequestLayout', '인바운드 요청', 'CBSS') // 함수 사용 예시에 인바운드 응답 처리 추가 $("#fromAdapter").change(function() { diff --git a/WebContent/jsp/onl/transaction/tracking/trackingManDetail.jsp b/WebContent/jsp/onl/transaction/tracking/trackingManDetail.jsp index 2f5db38..dd19585 100644 --- a/WebContent/jsp/onl/transaction/tracking/trackingManDetail.jsp +++ b/WebContent/jsp/onl/transaction/tracking/trackingManDetail.jsp @@ -15,6 +15,14 @@ @@ -919,14 +946,14 @@ html,hbody { - <%=localeMessage.getString("trackingDetail.eaiSvcName")%> + API ID <%-- " alt="" id="eaiSvcName" class="eaiSvcName_btn" /> --%> <%-- --%> <%=localeMessage.getString("trackingDetail.msgPrcssYMS")%> - <%=localeMessage.getString("trackingDetail.eaiSvcDesc")%> + API 명 ORG GUID @@ -994,7 +1021,7 @@ html,hbody { - + diff --git a/WebContent/jsp/onl/transaction/tracking/trackingManDetail2.jsp b/WebContent/jsp/onl/transaction/tracking/trackingManDetail2.jsp index 662975e..46a7821 100644 --- a/WebContent/jsp/onl/transaction/tracking/trackingManDetail2.jsp +++ b/WebContent/jsp/onl/transaction/tracking/trackingManDetail2.jsp @@ -23,7 +23,7 @@ var serviceType = null; var guid = null; //alert(window.dialogArguments.length); - debugger; + //debugger; if(window.dialogArguments != null && window.dialogArguments != undefined){ eaiBzwkDstcd = window.dialogArguments["eaiBzwkDstcd"]; msgDpstYMS = window.dialogArguments["msgDpstYMS"]; diff --git a/WebContent/jsp/onl/transaction/tracking/trackingManTransformpopup2.jsp b/WebContent/jsp/onl/transaction/tracking/trackingManTransformpopup2.jsp index 904f705..0949e5c 100644 --- a/WebContent/jsp/onl/transaction/tracking/trackingManTransformpopup2.jsp +++ b/WebContent/jsp/onl/transaction/tracking/trackingManTransformpopup2.jsp @@ -1675,7 +1675,7 @@ $(document).ready(function () { }); $("input[name=srcLayout],[name=tgtLayout]").dblclick(function(){ - debugger; + //debugger; var layoutName = $(this).val(); if($.trim(layoutName) =="") return; diff --git a/gradle.properties b/gradle.properties index 818a536..759e8ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx2g +org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true \ No newline at end of file diff --git a/kjb-docs/vulnerability/vulnerability-2.odt b/kjb-docs/vulnerability/vulnerability-2.odt new file mode 100644 index 0000000..f46ffda Binary files /dev/null and b/kjb-docs/vulnerability/vulnerability-2.odt differ diff --git a/src/main/java/com/eactive/eai/rms/common/exception/GlobalExceptionController.java b/src/main/java/com/eactive/eai/rms/common/exception/GlobalExceptionController.java index e0fd72b..3e39210 100644 --- a/src/main/java/com/eactive/eai/rms/common/exception/GlobalExceptionController.java +++ b/src/main/java/com/eactive/eai/rms/common/exception/GlobalExceptionController.java @@ -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; +// } +// } } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/common/login/MainController.java b/src/main/java/com/eactive/eai/rms/common/login/MainController.java index a43dda0..f118b33 100644 --- a/src/main/java/com/eactive/eai/rms/common/login/MainController.java +++ b/src/main/java/com/eactive/eai/rms/common/login/MainController.java @@ -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")); 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 da1d6ef..4c2b803 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 @@ -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 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) */ diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/logger/EAILogRepositoryImpl.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/logger/EAILogRepositoryImpl.java index 53f4852..7ac9a79 100644 --- a/src/main/java/com/eactive/eai/rms/data/entity/onl/logger/EAILogRepositoryImpl.java +++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/logger/EAILogRepositoryImpl.java @@ -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())); } diff --git a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java b/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java index 4769cc8..ea0a1fa 100644 --- a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java +++ b/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java @@ -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: {}****{}", 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 deleted file mode 100644 index 6ea4219..0000000 --- a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricAfterDTO.java +++ /dev/null @@ -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 엔드포인트용) - * - *

예시 출력 형식에 맞춤:

- *
- * {
- *   "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
- * }
- * 
- */ -@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); - } -} 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 1e2dbdc..18a4f48 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 @@ -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 metrics = obpGwMetricManService.findByTimesliceAfter(timesliceHour); + List 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 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 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; - } - } } diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricDTO.java b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricDTO.java index c0d0a0a..976e678 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricDTO.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricDTO.java @@ -8,32 +8,61 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; /** - * ObpGwMetric JSON 응답 DTO - * Entity 주석에 명시된 JSON Key 사용 + * ObpGwMetric JSON 응답 DTO (after-timeslice 엔드포인트용) + * + *

예시 출력 형식에 맞춤:

+ *
+ * {
+ *   "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
+ * }
+ * 
*/ @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); } } 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 814f13c..a815b2c 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 @@ -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 findByTimeslice(LocalDateTime timeslice) { - DataSourceContextHolder.setDataSourceType( - DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING)); - - List entities = obpGwMetricService.findByTimeslice(timeslice); - return entities.stream() - .map(ObpGwMetricDTO::from) - .collect(Collectors.toList()); - } - /** * 특정 시간대 이후의 GwMetric 데이터 조회 (REST API용) * after-timeslice 엔드포인트에서 사용 + * + *

조회 범위 제한:

+ *
    + *
  • pageSize 값을 KjbProperty.apiGwMetricPageSize에서 읽어옴 (기본값: 10000)
  • + *
  • 0일 경우 무제한 조회
  • + *
  • 정렬: timeslice ASC (오래된 데이터부터 반환)
  • + *
*/ - public List findByTimesliceAfter(LocalDateTime timeslice) { + public List findByTimesliceAfter(LocalDateTime timeslice) { DataSourceContextHolder.setDataSourceType( DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING)); - List entities = obpGwMetricService.findByTimesliceGreaterThanEqual(timeslice); + // KjbProperty에서 pageSize 읽기 + Integer pageSize = KjbPropertyHolder.get().getApiGwMetricPageSize(); + if (pageSize == null) { + pageSize = 10000; // 기본값 (null 안전 처리) + } + + // Service 호출 (limit 적용) + List entities = obpGwMetricService.findByTimesliceGreaterThanEqual(timeslice, pageSize); + return entities.stream() - .map(ObpGwMetricAfterDTO::from) + .map(ObpGwMetricDTO::from) .collect(Collectors.toList()); } diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java index c3f4cdb..028a040 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java @@ -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); diff --git a/src/main/java/com/eactive/eai/rms/onl/manage/rule/layoutsync/LayoutSyncController.java b/src/main/java/com/eactive/eai/rms/onl/manage/rule/layoutsync/LayoutSyncController.java index 15604d6..b8df9ea 100644 --- a/src/main/java/com/eactive/eai/rms/onl/manage/rule/layoutsync/LayoutSyncController.java +++ b/src/main/java/com/eactive/eai/rms/onl/manage/rule/layoutsync/LayoutSyncController.java @@ -404,7 +404,7 @@ public class LayoutSyncController extends OnlBaseAnnotationController implements String resultS = null; ServletInputStream sis = null; - HashMap param = new HashMap(); + HashMap 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 returnMap = new HashMap(); + HashMap returnMap = new HashMap<>(); if( command.equals("delete") ) { - HashMap vo = new HashMap(); + HashMap 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 vo = new HashMap(); @@ -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) { diff --git a/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingController.java b/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingController.java index 7cb03c2..feb724c 100644 --- a/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingController.java +++ b/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingController.java @@ -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 paramMap) { + + List 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 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> entity = new HttpEntity<>(requestBody, headers); + + Map 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 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 errorMap = objectMapper.readValue(errorBodyString, Map.class); + return ResponseEntity.status(e.getStatusCode()).body(errorMap); + } catch (Exception parseError) { + // 일반 텍스트를 보냈다면 수동으로 Map 생성 + Map 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 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); + } + } } diff --git a/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingService.java b/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingService.java index b960565..3432d99 100644 --- a/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingService.java +++ b/src/main/java/com/eactive/eai/rms/onl/transaction/tracking/DbTrackingService.java @@ -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;