UMS 응답 저장 및 상세조회
eapim-admin CI / build (push) Has been cancelled

This commit is contained in:
eastargh
2026-09-10 09:56:50 +09:00
parent 266644798f
commit 0b6f273132
5 changed files with 79 additions and 27 deletions
@@ -47,6 +47,8 @@
$('#sentDate').text(data.sentDateFull || ''); $('#sentDate').text(data.sentDateFull || '');
// 서버에서 마스킹+escape 된 안전 HTML // 서버에서 마스킹+escape 된 안전 HTML
$('#messageHtml').html(data.messageHtml || ''); $('#messageHtml').html(data.messageHtml || '');
// 응답내용(RESPONSE_DATA) — 원문이므로 text 로만 출력
$('#responseData').text(data.responseData || '');
// PENDING 건만 '실패 처리' 노출 (권한 제어는 buttonControl 이 담당) // PENDING 건만 '실패 처리' 노출 (권한 제어는 buttonControl 이 담당)
if (data.requestStatus !== 'PENDING') { if (data.requestStatus !== 'PENDING') {
@@ -142,6 +144,10 @@
<th>메세지 내용</th> <th>메세지 내용</th>
<td colspan="3"><div id="messageHtml" class="msg-detail"></div></td> <td colspan="3"><div id="messageHtml" class="msg-detail"></div></td>
</tr> </tr>
<tr>
<th>응답내용</th>
<td colspan="3"><div id="responseData" class="msg-detail"></div></td>
</tr>
</table> </table>
</div> </div>
</div> </div>
@@ -1,6 +1,7 @@
package com.eactive.eai.rms.ext.djb.ums.service; package com.eactive.eai.rms.ext.djb.ums.service;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
@@ -11,6 +12,7 @@ import java.nio.charset.Charset;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -62,13 +64,21 @@ public class UmsService {
throw new IllegalArgumentException("messageRequest is null"); throw new IllegalArgumentException("messageRequest is null");
} }
this.httpConnection(messageRequest); UmsResponse response = this.httpConnection(messageRequest);
return true; // HTTP 응답코드가 2xx 일 때만 SENT, 나머지는 FAILED
boolean success = response.getHttpStatus() >= 200 && response.getHttpStatus() < 300;
messageRequest.setRequestStatus(success ? "SENT" : "FAILED");
messageRequest.setSentDate(LocalDateTime.now());
messageRequest.setResponseData(response.getResponseData());
messageRequestService.save(messageRequest);
return success;
} }
private void httpConnection(MessageRequest messageRequest) throws Exception { private UmsResponse httpConnection(MessageRequest messageRequest) throws Exception {
HttpURLConnection conn = null; HttpURLConnection conn = null;
BufferedReader br = null; BufferedReader br = null;
log.debug("<<<HTTP Connection>>>:" + messageRequest.toString()); log.debug("<<<HTTP Connection>>>:" + messageRequest.toString());
@@ -101,18 +111,18 @@ public class UmsService {
os.close(); os.close();
} }
int responseCode = conn.getResponseCode();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("getContentType();" + conn.getContentType()); // 응답 콘텐츠 유형 구하기 log.debug("getContentType();" + conn.getContentType()); // 응답 콘텐츠 유형 구하기
log.debug("getResponsecode();" + conn.getResponseCode()); // 응답 코드 구하기 log.debug("getResponsecode();" + responseCode); // 응답 코드 구하기
log.debug("getResponseMessage():" + conn.getResponseMessage()); // 응답 메세지 구하기 log.debug("getResponseMessage():" + conn.getResponseMessage()); // 응답 메세지 구하기
} }
// http 요청 후 응답 받은 데이타를 버퍼에 쌓는다 // http 요청 후 응답 받은 데이타를 버퍼에 쌓는다
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) { InputStream is = (responseCode >= 200 && responseCode < 300) ? conn.getInputStream() : conn.getErrorStream();
br = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset)); if (is != null) {
} else { br = new BufferedReader(new InputStreamReader(is, charset));
br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), charset));
}
String inputLine; String inputLine;
sb = new StringBuffer(); sb = new StringBuffer();
@@ -121,8 +131,11 @@ public class UmsService {
} }
responseData = sb.toString(); responseData = sb.toString();
}
log.debug("UMS responseData:" + responseData);
return new UmsResponse(responseCode, responseData);
} finally { } finally {
// http 요청 및 응답 완료 후 BufferedReader를 닫는다 // http 요청 및 응답 완료 후 BufferedReader를 닫는다
if (br != null) { if (br != null) {
@@ -134,6 +147,25 @@ public class UmsService {
} }
} }
/** UMS HTTP 호출 결과(응답코드 + 응답본문) 보관용. */
private static class UmsResponse {
private final int httpStatus;
private final String responseData;
UmsResponse(int httpStatus, String responseData) {
this.httpStatus = httpStatus;
this.responseData = responseData;
}
int getHttpStatus() {
return httpStatus;
}
String getResponseData() {
return responseData;
}
}
/** /**
@@ -263,7 +295,7 @@ public class UmsService {
} else { } else {
dataVO.setAlmtk_snd_prfl_key(propertyService.getPropertyValue("Monitoring", "djb.ums.sms.almtk_snd_prtl_key.public", "")); // 제주은행 플러스친구아이디 dataVO.setAlmtk_snd_prfl_key(propertyService.getPropertyValue("Monitoring", "djb.ums.sms.almtk_snd_prtl_key.public", "")); // 제주은행 플러스친구아이디
} }
dataVO.setAlmtk_tmplt_cd(BZWK_DVCD + TEAM_DVCD + BZWK_DCLS_DVCD + "001"); // 템플릿코드 dataVO.setAlmtk_tmplt_cd("JJB_85959019001"); // 템플릿코드
dataVO.setAlmtk_err_ltrs_snd_yn("Y"); // 오류자문자발송여부 dataVO.setAlmtk_err_ltrs_snd_yn("Y"); // 오류자문자발송여부
dataVO.setAlmtk_btn_trnm_tycd("2"); // 카카오버튼전송방식 1-format string 2-JSON 3-XML dataVO.setAlmtk_btn_trnm_tycd("2"); // 카카오버튼전송방식 1-format string 2-JSON 3-XML
@@ -72,6 +72,7 @@ public class MessageRequestManService extends BaseService {
ui.setUmsUid(e.getUmsUid()); ui.setUmsUid(e.getUmsUid());
ui.setRequestStatus(e.getRequestStatus()); ui.setRequestStatus(e.getRequestStatus());
ui.setResponseData(e.getResponseData());
ui.setEaiInterfaceId(e.getEaiInterfaceId()); ui.setEaiInterfaceId(e.getEaiInterfaceId());
ui.setServiceId(e.getServiceId()); ui.setServiceId(e.getServiceId());
@@ -22,6 +22,9 @@ public class MessageRequestUI {
/* 본문 — 패턴 마스킹 + span 색상강조된 안전 HTML */ /* 본문 — 패턴 마스킹 + span 색상강조된 안전 HTML */
private String messageHtml; private String messageHtml;
/* UMS 응답 내용 (RESPONSE_DATA) — 원문 그대로, 화면에서는 text 로만 출력 */
private String responseData;
/* 수신자 (마스킹) */ /* 수신자 (마스킹) */
private String username; private String username;
private String email; private String email;
@@ -147,8 +147,8 @@ public class UmsDispatchService {
try { try {
transactionTemplate.execute(status -> { transactionTemplate.execute(status -> {
try { try {
// 상태(SENT/FAILED) 및 RESPONSE_DATA 저장은 umsService.send() 내부에서 처리한다.
umsService.send(message); umsService.send(message);
updateMessageStatus(message, "SENT");
return null; return null;
} catch (Exception e) { } catch (Exception e) {
// checked exception을 RuntimeException으로 감싸 전파 → TransactionTemplate이 rollback 후 re-throw // checked exception을 RuntimeException으로 감싸 전파 → TransactionTemplate이 rollback 후 re-throw
@@ -159,7 +159,8 @@ public class UmsDispatchService {
log.error("Failed to process message: {} - Error: {}", message.getId(), e.getMessage(), e); log.error("Failed to process message: {} - Error: {}", message.getId(), e.getMessage(), e);
try { try {
transactionTemplate.execute(s -> { transactionTemplate.execute(s -> {
updateMessageStatus(message, "FAILED"); // 응답 자체를 받지 못한 경우(네트워크/타임아웃 등) 예외 메시지를 RESPONSE_DATA 에 남긴다.
updateMessageStatus(message, "FAILED", toResponseData(e));
return null; return null;
}); });
} catch (Exception ex) { } catch (Exception ex) {
@@ -171,10 +172,19 @@ public class UmsDispatchService {
public void updateMessageStatus(MessageRequest message, String status) { public void updateMessageStatus(MessageRequest message, String status, String responseData) {
message.setRequestStatus(status); message.setRequestStatus(status);
message.setSentDate(LocalDateTime.now()); message.setSentDate(LocalDateTime.now());
if (responseData != null) {
message.setResponseData(responseData);
}
entityManager.merge(message); entityManager.merge(message);
entityManager.flush(); entityManager.flush();
} }
/** 예외를 RESPONSE_DATA 컬럼에 저장할 문자열로 변환한다. (RuntimeException 래퍼는 원인 예외로 풀어서 사용) */
private static String toResponseData(Throwable t) {
Throwable root = (t instanceof RuntimeException && t.getCause() != null) ? t.getCause() : t;
return String.valueOf(root);
}
} }