diff --git a/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.bin b/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.bin index 890a38b..38e9902 100644 Binary files a/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.bin and b/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.bin differ diff --git a/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.lock b/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.lock index b58c0b0..647cd15 100644 Binary files a/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.lock and b/gukyuin/status-update/.gradle/8.14/executionHistory/executionHistory.lock differ diff --git a/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.bin b/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.bin index ed0eb6d..c336a95 100644 Binary files a/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.bin and b/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.bin differ diff --git a/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.lock b/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.lock index 6cae21c..97f50d6 100644 Binary files a/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.lock and b/gukyuin/status-update/.gradle/8.14/fileHashes/fileHashes.lock differ diff --git a/gukyuin/status-update/.gradle/8.14/fileHashes/resourceHashesCache.bin b/gukyuin/status-update/.gradle/8.14/fileHashes/resourceHashesCache.bin index e0b3c4d..78842ee 100644 Binary files a/gukyuin/status-update/.gradle/8.14/fileHashes/resourceHashesCache.bin and b/gukyuin/status-update/.gradle/8.14/fileHashes/resourceHashesCache.bin differ diff --git a/gukyuin/status-update/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/gukyuin/status-update/.gradle/buildOutputCleanup/buildOutputCleanup.lock index bc3fc52..f2db5d2 100644 Binary files a/gukyuin/status-update/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/gukyuin/status-update/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/gukyuin/status-update/.gradle/file-system.probe b/gukyuin/status-update/.gradle/file-system.probe index e996b58..797408e 100644 Binary files a/gukyuin/status-update/.gradle/file-system.probe and b/gukyuin/status-update/.gradle/file-system.probe differ diff --git a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient$ExternalCallResult.class b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient$ExternalCallResult.class index cb23291..c510012 100644 Binary files a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient$ExternalCallResult.class and b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient$ExternalCallResult.class differ diff --git a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.class b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.class index 7214690..59718ff 100644 Binary files a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.class and b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.class differ diff --git a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.class b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.class index 214c087..334952a 100644 Binary files a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.class and b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.class differ diff --git a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.class b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.class index e691f18..e5a6f5f 100644 Binary files a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.class and b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.class differ diff --git a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.class b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.class index ac376a8..2087f3d 100644 Binary files a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.class and b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.class differ diff --git a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.class b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.class index a01b53e..166f06f 100644 Binary files a/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.class and b/gukyuin/status-update/build/classes/java/main/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.class differ diff --git a/gukyuin/status-update/build/libs/status-update.jar b/gukyuin/status-update/build/libs/status-update.jar index e0b2fc0..c0fa09f 100644 Binary files a/gukyuin/status-update/build/libs/status-update.jar and b/gukyuin/status-update/build/libs/status-update.jar differ diff --git a/gukyuin/status-update/build/tmp/compileJava/previous-compilation-data.bin b/gukyuin/status-update/build/tmp/compileJava/previous-compilation-data.bin index 1cf55a6..e158473 100644 Binary files a/gukyuin/status-update/build/tmp/compileJava/previous-compilation-data.bin and b/gukyuin/status-update/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java index e4e656d..d5b5c22 100644 --- a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java +++ b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java @@ -25,46 +25,105 @@ public class ExternalHttpClient { public ExternalCallResult call( String url, HttpMethod method, Object body, HttpHeaders headers, Class responseType) { + long start = System.currentTimeMillis(); + + log.info("[API-REQ] method={}, url={}", method, url); + // responseType 기반으로 Accept 동적 세팅 HttpHeaders resolvedHeaders = resolveHeaders(headers, responseType); + + log.debug("[API-REQ] headers={}", resolvedHeaders); logRequestBody(body); HttpEntity entity = new HttpEntity<>(body, resolvedHeaders); try { + // String: raw bytes -> UTF-8 string if (responseType == String.class) { + ResponseEntity res = restTemplate.exchange(url, method, entity, byte[].class); + String raw = (res.getBody() == null) ? null : new String(res.getBody(), StandardCharsets.UTF_8); + long elapsed = System.currentTimeMillis() - start; + + log.info( + "[API-RES] method={}, url={}, status={}, elapsed={}ms", + method, + url, + res.getStatusCodeValue(), + elapsed); + + log.debug("[API-RES] body={}", raw); + @SuppressWarnings("unchecked") T casted = (T) raw; + return new ExternalCallResult<>(res.getStatusCodeValue(), true, casted, null); } // byte[]: raw bytes로 받고, JSON이면 에러로 처리 if (responseType == byte[].class) { + ResponseEntity res = restTemplate.exchange(url, method, entity, byte[].class); + long elapsed = System.currentTimeMillis() - start; + + log.info( + "[API-RES] method={}, url={}, status={}, elapsed={}ms", + method, + url, + res.getStatusCodeValue(), + elapsed); + MediaType ct = res.getHeaders().getContentType(); byte[] bytes = res.getBody(); if (isJsonLike(ct)) { + String err = (bytes == null) ? null : new String(bytes, StandardCharsets.UTF_8); + + log.warn("[API-RES] JSON error body={}", err); + return new ExternalCallResult<>(res.getStatusCodeValue(), false, null, err); } @SuppressWarnings("unchecked") T casted = (T) bytes; + return new ExternalCallResult<>(res.getStatusCodeValue(), true, casted, null); } // DTO 등: 일반 역직렬화 ResponseEntity res = restTemplate.exchange(url, method, entity, responseType); + + long elapsed = System.currentTimeMillis() - start; + + log.info( + "[API-RES] method={}, url={}, status={}, elapsed={}ms", + method, + url, + res.getStatusCodeValue(), + elapsed); + + log.debug("[API-RES] body={}", res.getBody()); + return new ExternalCallResult<>(res.getStatusCodeValue(), true, res.getBody(), null); } catch (HttpStatusCodeException e) { + + long elapsed = System.currentTimeMillis() - start; + + log.error( + "[API-ERROR] method={}, url={}, status={}, elapsed={}ms, body={}", + method, + url, + e.getStatusCode().value(), + elapsed, + e.getResponseBodyAsString()); + return new ExternalCallResult<>( e.getStatusCode().value(), false, null, e.getResponseBodyAsString()); } diff --git a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.java b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.java index 9988dd4..73b4110 100644 --- a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.java +++ b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/core/GukYuinPnuCntUpdateJobCoreService.java @@ -15,8 +15,8 @@ public class GukYuinPnuCntUpdateJobCoreService { } @Transactional - public void updateGukYuinContListPnuUpdateCnt() { - gukYuinPnuCntUpdateRepository.updateGukYuinContListPnuUpdateCnt(); + public int updateGukYuinContListPnuUpdateCnt() { + return gukYuinPnuCntUpdateRepository.updateGukYuinContListPnuUpdateCnt(); } @Transactional diff --git a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.java b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.java index b4e7e1d..0940243 100644 --- a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.java +++ b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryCustom.java @@ -2,7 +2,7 @@ package com.kamco.cd.kamcoback.postgres.repository.gukyuin; public interface GukYuinPnuCntUpdateJobRepositoryCustom { - void updateGukYuinContListPnuUpdateCnt(); + int updateGukYuinContListPnuUpdateCnt(); void updateGukYuinApplyStatus(String uid, String status); } diff --git a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.java b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.java index b54a059..d87629d 100644 --- a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.java +++ b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/postgres/repository/gukyuin/GukYuinPnuCntUpdateJobRepositoryImpl.java @@ -20,7 +20,7 @@ public class GukYuinPnuCntUpdateJobRepositoryImpl @PersistenceContext private EntityManager em; @Override - public void updateGukYuinContListPnuUpdateCnt() { + public int updateGukYuinContListPnuUpdateCnt() { String sql = """ update tb_map_sheet_anal_data_inference_geom p @@ -33,7 +33,7 @@ public class GukYuinPnuCntUpdateJobRepositoryImpl where p.geo_uid = c_count.geo_uid and p.pnu != c_count.actual_count; """; - jdbcTemplate.update(sql); + return jdbcTemplate.update(sql); } @Override diff --git a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.java b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.java index 9548a51..79a538f 100644 --- a/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.java +++ b/gukyuin/status-update/src/main/java/com/kamco/cd/kamcoback/service/GukYuinApiStatusJobService.java @@ -23,11 +23,6 @@ public class GukYuinApiStatusJobService { @Value("${spring.profiles.active}") private String profile; - /** - * 실행중인 profile - * - * @return - */ private boolean isLocalProfile() { return "local".equalsIgnoreCase(profile); } @@ -35,34 +30,109 @@ public class GukYuinApiStatusJobService { /** 매일 00시에 pnu cnt 업데이트 */ public void findGukYuinPnuCntUpdate() { + long jobStart = System.currentTimeMillis(); + log.info("[JOB-START] GukYuin PNU CNT Update Job start profile={}", profile); + + log.info("추론 learn 테이블의 apply_status = IN_PROGRESS 인 회차 조회"); + log.info("국유인 연동 시작 상태 : IN_PROGRESS 로 업데이트 된다."); + log.info("국유인에서 shp 파일 모두 다운로드 되는지 확인 후 100%가 되면 PNU_COMPLETED 로 업데이트 한다."); List list = gukYuinJobCoreService.findGukyuinApplyStatusUidList( List.of(GukYuinStatus.IN_PROGRESS.getId())); - if (list.isEmpty()) { + + int total = list == null ? 0 : list.size(); + + log.info("[Step 1] 대상 추론 회차 UID 갯수 count={}", total); + + if (list == null || list.isEmpty()) { + log.info("[JOB-END] 처리 대상 없음"); return; } + int success = 0; + int skip = 0; + int fail = 0; + for (LearnKeyDto dto : list) { + + long itemStart = System.currentTimeMillis(); + try { + log.info("[Step 2] 처리 시작 uid={}, chnDtctMstId={}", dto.getUid(), dto.getChnDtctMstId()); + + log.info("[Step 3] 국유인 API 호출 시작 uid={}", dto.getUid()); + ChngDetectMastDto.ResultDto result = gukYuinApiService.listChnDtctId(dto.getUid(), "Y"); - if (result == null || result.getResult() == null || result.getResult().isEmpty()) { - log.warn("[GUKYUIN] empty result chnDtctMstId={}", dto.getChnDtctMstId()); + if (result == null) { + log.warn("[Step 3] API result NULL uid={}", dto.getUid()); + skip++; continue; } + if (result.getResult() == null || result.getResult().isEmpty()) { + log.warn("[Step 3] API result empty chnDtctMstId={}", dto.getChnDtctMstId()); + skip++; + continue; + } + + log.info("[Step 3] API result size={}", result.getResult().size()); + ChngDetectMastDto.Basic basic = result.getResult().getFirst(); + log.debug("[Step 4] API first result={}", basic); + Integer progress = basic.getExcnPgrt() == null ? null : Integer.parseInt(basic.getExcnPgrt().trim()); + + log.info("[Step 4] 실행 진행률 progress={}", progress); + if (progress != null && progress == 100) { - gukYuinPnuCntUpdateJobCoreService.updateGukYuinContListPnuUpdateCnt(); + log.info("[Step 5] progress 100 확인 → PNU CNT update 실행"); + + log.info( + "=== tb_pnu 에 insert 된 데이터 중 tb_map_sheet_anal_data_inference_geom 의 pnu (cnt)값이 다른 것 update"); + int updateCnt = gukYuinPnuCntUpdateJobCoreService.updateGukYuinContListPnuUpdateCnt(); + + log.info("[Step 5] PNU CNT update 완료 updatedRows={}", updateCnt); + log.info( + "[Step 6] 추론 learn 테이블 apply_status={} 로 업데이트", GukYuinStatus.PNU_COMPLETED.getId()); gukYuinPnuCntUpdateJobCoreService.updateGukYuinApplyStatus( dto.getUid(), GukYuinStatus.PNU_COMPLETED.getId()); + + log.info( + "[Step 6] apply_status 변경 완료 uid={}, status={}", + dto.getUid(), + GukYuinStatus.PNU_COMPLETED.getId()); + + success++; + + } else { + log.info("[Step 5] progress != 100 skip uid={}, progress={}", dto.getUid(), progress); + skip++; } + + log.info( + "[ITEM-END] uid={} elapsed={}ms", dto.getUid(), System.currentTimeMillis() - itemStart); + } catch (Exception e) { - log.error("[GUKYUIN] failed uid={}", dto.getChnDtctMstId(), e); + + fail++; + + log.error( + "[ITEM-ERROR] uid={} elapsed={}ms", + dto.getChnDtctMstId(), + System.currentTimeMillis() - itemStart, + e); } } + + log.info( + "[JOB-END] total={}, success={}, skip={}, fail={}, elapsed={}ms", + total, + success, + skip, + fail, + System.currentTimeMillis() - jobStart); } }