release: 2026-03-27.3 (7건 커밋) #121

병합
htlee develop 에서 main 로 7 commits 를 머지했습니다 2026-03-27 08:14:57 +09:00
3개의 변경된 파일40개의 추가작업 그리고 33개의 파일을 삭제
Showing only changes of commit df957be2fe - Show all commits

파일 보기

@ -191,7 +191,11 @@ public class GisControllerV2 {
)
@RequestBody VesselTracksRequest request,
HttpServletRequest httpRequest) {
return gisServiceV2.getVesselTracksV2(request, getClientIp(httpRequest));
return gisServiceV2.getVesselTracksV2(request, getClientIp(httpRequest), getClientId(httpRequest));
}
private String getClientId(HttpServletRequest request) {
return gc.mda.signal_batch.global.config.WebSocketStompConfig.extractClientIdFromRequest(request);
}
private String getClientIp(HttpServletRequest request) {

파일 보기

@ -285,7 +285,7 @@ public class GisServiceV2 {
/**
* 선박별 항적 조회 V2 (캐시 + Semaphore + 간소화 + ChnPrmShip enrichment)
*/
public List<CompactVesselTrack> getVesselTracksV2(VesselTracksRequest request, String clientIp) {
public List<CompactVesselTrack> getVesselTracksV2(VesselTracksRequest request, String clientIp, String clientId) {
String queryId = "rest-vessels-" + UUID.randomUUID().toString().substring(0, 8);
long startMs = System.currentTimeMillis();
boolean slotAcquired = false;
@ -329,7 +329,7 @@ public class GisServiceV2 {
result.size(), request.getVessels().size(),
dailyTrackCacheManager.isEnabled(), request.isIncludeChnPrmShip());
enqueueRestMetric(queryId, request, result, startMs, clientIp);
enqueueRestMetric(queryId, request, result, startMs, clientIp, clientId);
return result;
@ -347,7 +347,7 @@ public class GisServiceV2 {
}
private void enqueueRestMetric(String queryId, VesselTracksRequest request,
List<CompactVesselTrack> result, long startMs, String clientIp) {
List<CompactVesselTrack> result, long startMs, String clientIp, String clientId) {
try {
int totalPoints = result.stream().mapToInt(CompactVesselTrack::getPointCount).sum();
long responseBytes = (long) result.size() * 200 + (long) totalPoints * 40;
@ -367,6 +367,7 @@ public class GisServiceV2 {
.elapsedMs(System.currentTimeMillis() - startMs)
.status("COMPLETED")
.clientIp(clientIp)
.clientId(clientId)
.build());
} catch (Exception e) {
log.debug("Failed to enqueue REST metric: {}", e.getMessage());

파일 보기

@ -235,11 +235,16 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
return "unknown";
}
private String extractEmailFromJwtCookie(HttpServletRequest request) {
return extractClientIdFromRequest(request);
}
}
/**
* GC_SESSION 쿠키에서 JWT payload의 email 클레임 추출.
* GC_SESSION 쿠키에서 JWT payload의 email 클레임 추출 (REST/WebSocket 공용).
* JWT 검증은 nginx auth_request에서 이미 완료 여기서는 payload 디코딩만 수행.
*/
private String extractEmailFromJwtCookie(HttpServletRequest request) {
public static String extractClientIdFromRequest(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies == null) return null;
@ -253,12 +258,10 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
if (token == null || token.isEmpty()) return null;
try {
// JWT: header.payload.signature payload만 Base64URL 디코딩
String[] parts = token.split("\\.");
if (parts.length < 2) return null;
String payload = new String(Base64.getUrlDecoder().decode(parts[1]));
// 간단한 JSON 파싱 (Jackson 의존 없이): "email":"value" 추출
int emailIdx = payload.indexOf("\"email\"");
if (emailIdx < 0) return null;
@ -273,4 +276,3 @@ public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
}
}
}
}