diff --git a/WebContent/jsp/onl/apim/webhook/webhookSendLogManDetail.jsp b/WebContent/jsp/onl/apim/webhook/webhookSendLogManDetail.jsp index c22b9f9..f1e9291 100644 --- a/WebContent/jsp/onl/apim/webhook/webhookSendLogManDetail.jsp +++ b/WebContent/jsp/onl/apim/webhook/webhookSendLogManDetail.jsp @@ -43,6 +43,7 @@ $('#sendBy').text(data.sendBy || ''); $('#sentAt').text(data.sentAt || ''); $('#signature').text(data.signature || ''); + $('#userSecret').text(data.userSecret || ''); $('#errorMessage').text(data.errorMessage || ''); $('#payload').text(data.payload || ''); $('#responseBody').text(data.responseBody || ''); @@ -116,7 +117,9 @@ Signature - + + User Secret + Payload diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/djb/webhook/WebhookSendLog.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/djb/webhook/WebhookSendLog.java index 1900d34..5b1cd5a 100644 --- a/src/main/java/com/eactive/eai/rms/data/entity/onl/djb/webhook/WebhookSendLog.java +++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/djb/webhook/WebhookSendLog.java @@ -71,6 +71,9 @@ public class WebhookSendLog { @Column(name = "SEND_BY", length = 100) private String sendBy; + + @Column(name = "USER_SECRET") + private String userSecret; /* Boolean 편의 메서드 */ public void setSuccess(Boolean success) { diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendLogUI.java b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendLogUI.java index 7b9afac..ab7f0e3 100644 --- a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendLogUI.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendLogUI.java @@ -24,6 +24,7 @@ public class WebhookSendLogUI { private String payload; private String signature; + private String userSecret; private Integer statusCode; private String responseBody; diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendRequest.java b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendRequest.java index 3130aff..b8be05d 100644 --- a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendRequest.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/dto/WebhookSendRequest.java @@ -12,5 +12,6 @@ public class WebhookSendRequest { private String eventType; private String secret; private String reverseProxyPath; + private String userSecret; private Object data; } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookSendLogManService.java b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookSendLogManService.java index dec6936..6901cc5 100644 --- a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookSendLogManService.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookSendLogManService.java @@ -157,6 +157,7 @@ public class WebhookSendLogManService extends BaseService { ui.setProxyUrl(e.getProxyUrl()); ui.setPayload(e.getPayload()); ui.setSignature(e.getSignature()); + ui.setUserSecret(e.getUserSecret()); ui.setStatusCode(e.getStatusCode()); ui.setResponseBody(e.getResponseBody()); ui.setSuccess(e.getSuccess()); diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookService.java b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookService.java index ef2472d..c0bfdae 100644 --- a/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookService.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/webhook/service/WebhookService.java @@ -67,7 +67,7 @@ public class WebhookService { String reverseProxyUrl = monitoringContext.getProperty(MonitoringContext.RMS_WEBHOOK_REVERSE_PROXY_URL); List tuples = new JPAQueryFactory(entityManager) - .select(req.orgId, req.targetUrl, req.secret, org.reverseProxyPath, api.id.apiId) + .select(req.orgId, req.targetUrl, req.secret, req.userSecret, org.reverseProxyPath, api.id.apiId) .from(req) .join(evt).on(req.id.eq(evt.id.webhookReqId)) .join(api).on(req.id.eq(api.id.webhookReqId)) @@ -84,8 +84,9 @@ public class WebhookService { WebhookSendRequest wr = new WebhookSendRequest(); wr.setOrgId(t.get(req.orgId)); wr.setTargetUrl(t.get(req.targetUrl)); - wr.setProxyUrl(this.getProxyUrl(reverseProxyUrl, t.get(org.reverseProxyPath), t.get(req.targetUrl))); + wr.setProxyUrl(this.getProxyUrl(reverseProxyUrl, t.get(org.reverseProxyPath))); wr.setSecret(t.get(req.secret)); + wr.setUserSecret(t.get(req.userSecret)); wr.setEventType(event); wr.setData(new ArrayList()); return wr; @@ -104,17 +105,17 @@ public class WebhookService { } //reverse proxy 서버로 발송하기 위한 url 만든다 - private String getProxyUrl(String proxyUrl, String path, String targetUrl) { + private String getProxyUrl(String proxyUrl, String path) { String base = stripTrailingSlash(proxyUrl); String normalizedPath = stripSlashes(path); - // scheme://host[:port] 부분만 제거하고 이후 path/query/fragment는 그대로 유지 - String targetPath = targetUrl.replaceFirst("^[a-zA-Z][a-zA-Z0-9+.-]*://[^/]+", ""); +// // scheme://host[:port] 부분만 제거하고 이후 path/query/fragment는 그대로 유지 +// String targetPath = targetUrl.replaceFirst("^[a-zA-Z][a-zA-Z0-9+.-]*://[^/]+", ""); StringBuilder url = new StringBuilder(base); if (!normalizedPath.isEmpty()) { url.append('/').append(normalizedPath); } - url.append(targetPath); +// url.append(targetPath); return url.toString(); } @@ -152,7 +153,9 @@ public class WebhookService { String targetUrl = req.getTargetUrl(); String proxyUrl = req.getProxyUrl(); String secret = req.getSecret(); + String userSecret = req.getUserSecret(); String eventType = req.getEventType(); + String message = getMessage(eventType); Object data = req.getData(); WebhookSendLog sendLog = new WebhookSendLog(); @@ -160,11 +163,12 @@ public class WebhookService { sendLog.setTargetUrl(targetUrl); sendLog.setProxyUrl(proxyUrl); sendLog.setEventType(eventType); + sendLog.setUserSecret(userSecret); sendLog.setSendBy(ContainerUtil.getInstanceName()); try { // 1. Payload 생성 - WebhookPayload webhookPayload = WebhookPayload.of(eventType, data); + WebhookPayload webhookPayload = WebhookPayload.of(eventType, message, data); String payloadJson = objectMapper.writeValueAsString(webhookPayload); sendLog.setPayload(payloadJson); @@ -175,9 +179,10 @@ public class WebhookService { // 3. HTTP 요청 헤더 구성 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - headers.set("X-Webhook-Signature", "sha256=" + signature); - headers.set("X-Webhook-Event", eventType); - headers.set("X-Webhook-Timestamp", String.valueOf(webhookPayload.getTimestamp())); + headers.set("x-webhook-signature", "sha256=" + signature); + headers.set("x-webhook-event", eventType); + headers.set("x-webhook-secret", userSecret); + headers.set("x-webhook-timestamp", String.valueOf(webhookPayload.getTimestamp())); // 4. 발송 (재시도 포함) int retryCount = monitoringContext.getIntProperty(MonitoringContext.RMS_WEBHOOK_RETRY_COUNT, DEFAULT_RETRY_COUNT); @@ -213,7 +218,18 @@ public class WebhookService { } - + private String getMessage(String event) { + switch (event) { + case "CHECK_START": return "API 서비스 점검이 시작되었습니다"; //점검 + case "CHECK_END": return "API 서비스 점검이 종료되었습니다"; //정상 + case "ERROR_START": return "API 서비스 장애가 발생하였습니다"; //장애 + case "ERROR_END": return "API 서비스 장애가 복구되었습니다"; //정상 + case "DELAY_START": return "API 서비스 지연이 발생하였습니다"; //지연 + case "DELAY_END": return "API 서비스 지연이 복구되었습니다"; //정상 + default: + return "Webhook 메세지"; + } + } /** * 재시도 포함 HTTP 발송