diff --git a/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java b/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java index 4e7b7acf..013e01b5 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java @@ -1,30 +1,71 @@ package com.kamco.cd.kamcoback.config.resttemplate; import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.RestTemplate; @Component +@Log4j2 @RequiredArgsConstructor public class ExternalHttpClient { private final RestTemplate restTemplate; - public ResponseEntity exchange( - String url, HttpMethod method, Object body, HttpHeaders headers, Class responseType) { - HttpEntity entity = new HttpEntity<>(body, headers); - return restTemplate.exchange(url, method, entity, responseType); - } - public ExternalCallResult call( String url, HttpMethod method, Object body, HttpHeaders headers, Class responseType) { - ResponseEntity res = exchange(url, method, body, headers, responseType); - int code = res.getStatusCodeValue(); - return new ExternalCallResult<>(code, code >= 200 && code < 300, res.getBody()); + + HttpEntity entity = new HttpEntity<>(body, headers); + + // 요청 로그 + log.info("[HTTP-REQ] {} {}", method, url); + if (body != null) { + log.debug("[HTTP-REQ-BODY] {}", body); + } + + try { + ResponseEntity res = restTemplate.exchange(url, method, entity, responseType); + + int code = res.getStatusCodeValue(); + + // 응답 로그 + log.info("[HTTP-RES] {} {} -> {}", method, url, code); + log.debug("[HTTP-RES-BODY] {}", res.getBody()); + + return new ExternalCallResult<>(code, code >= 200 && code < 300, res.getBody()); + + } catch (HttpClientErrorException.NotFound e) { + log.info("[HTTP-RES] {} {} -> 404 (Not Found)", method, url); + log.debug("[HTTP-RES-BODY] {}", e.getResponseBodyAsString()); + + return new ExternalCallResult<>(404, false, null); + + } catch (HttpClientErrorException e) { + // 기타 4xx + log.warn( + "[HTTP-ERR] {} {} -> {} body={}", + method, + url, + e.getStatusCode().value(), + e.getResponseBodyAsString()); + throw e; + + } catch (HttpServerErrorException e) { + // 5xx + log.error( + "[HTTP-ERR] {} {} -> {} body={}", + method, + url, + e.getStatusCode().value(), + e.getResponseBodyAsString()); + throw e; + } } public record ExternalCallResult(int statusCode, boolean success, T body) {} diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java index b946c6ab..19deebad 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -139,6 +140,25 @@ public class InferenceResultApiController { return ApiResponseDto.ok(uuid); } + @Operation(summary = "추론 종료", description = "추론 종료") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "201", + description = "종료 성공", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = Page.class))), + @ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content), + @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content) + }) + @DeleteMapping("/end") + public ApiResponseDto getInferenceGeomList() { + inferenceResultService.deleteInferenceEnd(); + return null; + } + @Operation(summary = "분석 모델 선택 조회", description = "변화탐지 실행 정보 입력 모델선택 팝업 ") @ApiResponses( value = { diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java index 1af57e25..653e1aef 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceResultService.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.kamco.cd.kamcoback.common.exception.CustomApiException; +import com.kamco.cd.kamcoback.common.utils.UserUtil; import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient; import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult; import com.kamco.cd.kamcoback.inference.dto.InferenceDetailDto; @@ -65,9 +66,14 @@ public class InferenceResultService { @Value("${inference.url}") private String inferenceUrl; + @Value("${inference.batch-url}") + private String batchUrl; + @Value("${spring.profiles.active}") private String profile; + private final UserUtil userUtil; + /** * 추론관리 목록 * @@ -84,7 +90,11 @@ public class InferenceResultService { * @return */ public UUID getProcessing() { - return inferenceResultCoreService.getProcessing(); + SaveInferenceAiDto dto = inferenceResultCoreService.getProcessing(); + if (dto == null) { + return null; + } + return dto.getUuid(); } /** @@ -184,7 +194,7 @@ public class InferenceResultService { m1.setPred_requests_areas(predRequestsAreas); // ai 추론 실행 api 호출 - Long batchId = 0L; // ensureAccepted(m1); + Long batchId = ensureAccepted(m1); // ai 추론 실행후 응답값 update SaveInferenceAiDto saveInferenceAiDto = new SaveInferenceAiDto(); @@ -487,4 +497,33 @@ public class InferenceResultService { public Page getInferenceGeomList(String uuid, SearchGeoReq searchGeoReq) { return inferenceResultCoreService.getInferenceGeomList(uuid, searchGeoReq); } + + /** 추론 종료 */ + @Transactional + public void deleteInferenceEnd() { + SaveInferenceAiDto dto = inferenceResultCoreService.getProcessing(); + if (dto == null) { + throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND); + } + Long batchId = dto.getBatchId(); + String url = batchUrl + "/" + batchId; + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(List.of(MediaType.APPLICATION_JSON)); + + ExternalCallResult result = + externalHttpClient.call(url, HttpMethod.DELETE, dto, headers, String.class); + + if (!result.success()) { + throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND); + } + System.out.println(result); + + SaveInferenceAiDto request = new SaveInferenceAiDto(); + request.setStatus(Status.END.getId()); + request.setUuid(dto.getUuid()); + request.setUpdateUid(userUtil.getId()); + inferenceResultCoreService.update(request); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java index a78ff0b4..0a521c4d 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/core/InferenceResultCoreService.java @@ -21,6 +21,7 @@ import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearn5kEntity; import com.kamco.cd.kamcoback.postgres.entity.MapSheetLearnEntity; +import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetAnalDataInferenceRepository; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetLearn5kRepository; import com.kamco.cd.kamcoback.postgres.repository.Inference.MapSheetLearnRepository; @@ -50,6 +51,7 @@ public class InferenceResultCoreService { private final MapSheetLearnRepository mapSheetLearnRepository; private final MapInkx5kRepository mapInkx5kRepository; private final MapSheetLearn5kRepository mapSheetLearn5kRepository; + private final InferenceResultRepository inferenceResultRepository; private final EntityManager entityManager; private final UserUtil userUtil; @@ -379,17 +381,26 @@ public class InferenceResultCoreService { * * @return */ - public UUID getProcessing() { - return mapSheetLearnRepository.getProcessing(); - } + public SaveInferenceAiDto getProcessing() { + MapSheetLearnEntity entity = mapSheetLearnRepository.getProcessing(); - /** - * @param compareYear 비교년도 - * @param targetYear 기준년도 - * @return - */ - public Integer getLearnStage(Integer compareYear, Integer targetYear) { - return mapSheetLearnRepository.getLearnStage(compareYear, targetYear); + if (entity == null) { + return null; + } + + SaveInferenceAiDto dto = new SaveInferenceAiDto(); + dto.setUuid(entity.getUuid()); + + if (entity.getM3ModelBatchId() != null) { + dto.setBatchId(entity.getM3ModelBatchId()); + } + if (entity.getM2ModelBatchId() != null) { + dto.setBatchId(entity.getM2ModelBatchId()); + } + if (entity.getM1ModelBatchId() != null) { + dto.setBatchId(entity.getM1ModelBatchId()); + } + return dto; } public AnalResultInfo getInferenceResultInfo(String uuid) { @@ -403,4 +414,8 @@ public class InferenceResultCoreService { public Page getInferenceGeomList(String uuid, SearchGeoReq searchGeoReq) { return mapSheetLearnRepository.getInferenceGeomList(uuid, searchGeoReq); } + + public void upsertGeomsFromInferenceResults(Long id) { + int inferenceGeomCnt = inferenceResultRepository.upsertGeomsFromInferenceResults(); + } } diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java index ec5f5eda..d6c4b8b0 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryCustom.java @@ -28,7 +28,7 @@ public interface MapSheetLearnRepositoryCustom { InferenceStatusDetailDto getInferenceStatus(UUID uuid); - UUID getProcessing(); + MapSheetLearnEntity getProcessing(); Integer getLearnStage(Integer compareYear, Integer targetYear); diff --git a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java index d58f9b53..381b63b5 100644 --- a/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java +++ b/src/main/java/com/kamco/cd/kamcoback/postgres/repository/Inference/MapSheetLearnRepositoryImpl.java @@ -259,9 +259,9 @@ public class MapSheetLearnRepositoryImpl implements MapSheetLearnRepositoryCusto * * @return */ - public UUID getProcessing() { + public MapSheetLearnEntity getProcessing() { return queryFactory - .select(mapSheetLearnEntity.uuid) + .select(mapSheetLearnEntity) .from(mapSheetLearnEntity) .where(mapSheetLearnEntity.status.eq("IN_PROGRESS")) .fetchOne(); diff --git a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java index fb640a53..56980e25 100644 --- a/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java +++ b/src/main/java/com/kamco/cd/kamcoback/scheduler/service/MapSheetInferenceJobService.java @@ -133,6 +133,10 @@ public class MapSheetInferenceJobService { externalHttpClient.call(url, HttpMethod.GET, null, jsonHeaders(), String.class); int status = result.statusCode(); + if (status == 404) { + log.info("Batch not found. batchId={}", batchId); + return null; + } if (status < 200 || status >= 300) { return null; }