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 bd3abffd..fc5b2d06 100644 --- a/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/inference/InferenceResultApiController.java @@ -8,6 +8,7 @@ import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceServerStatusDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.InferenceStatusDetailDto; import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.ResultList; +import com.kamco.cd.kamcoback.inference.service.InferenceAsyncService; import com.kamco.cd.kamcoback.inference.service.InferenceResultService; import com.kamco.cd.kamcoback.log.dto.AuditLogDto; import com.kamco.cd.kamcoback.log.dto.AuditLogDto.DownloadReq; @@ -55,6 +56,7 @@ import org.springframework.web.bind.annotation.RestController; public class InferenceResultApiController { private final InferenceResultService inferenceResultService; + private final InferenceAsyncService inferenceAsyncService; private final MapSheetMngService mapSheetMngService; private final ModelMngService modelMngService; private final RangeDownloadResponder rangeDownloadResponder; @@ -177,7 +179,7 @@ public class InferenceResultApiController { @DeleteMapping("/end") public ApiResponseDto getInferenceGeomList() { // UUID uuid = inferenceResultService.deleteInferenceEnd(); - UUID uuid = inferenceResultService.asyncInferenceEnd(); + UUID uuid = inferenceAsyncService.asyncInferenceEnd(); return ApiResponseDto.ok(uuid); } diff --git a/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceAsyncService.java b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceAsyncService.java new file mode 100644 index 00000000..81a97475 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/inference/service/InferenceAsyncService.java @@ -0,0 +1,117 @@ +package com.kamco.cd.kamcoback.inference.service; + +import com.kamco.cd.kamcoback.common.exception.CustomApiException; +import com.kamco.cd.kamcoback.common.inference.service.InferenceCommonService; +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.InferenceResultDto.SaveInferenceAiDto; +import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Status; +import com.kamco.cd.kamcoback.postgres.core.AuditLogCoreService; +import com.kamco.cd.kamcoback.postgres.core.InferenceResultCoreService; +import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService; +import com.kamco.cd.kamcoback.postgres.core.ModelMngCoreService; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** 추론 관리 */ +@Service +@Slf4j +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class InferenceAsyncService { + + private final InferenceResultCoreService inferenceResultCoreService; + private final MapSheetMngCoreService mapSheetMngCoreService; + private final ModelMngCoreService modelMngCoreService; + private final AuditLogCoreService auditLogCoreService; + private final InferenceCommonService inferenceCommonService; + + private final ExternalHttpClient externalHttpClient; + private final UserUtil userUtil; + + @Value("${inference.batch-url}") + private String batchUrl; + + @Value("${inference.inference-server-name}") + private String inferenceServerName; + + @Value("${file.dataset-dir}") + private String datasetDir; + + @Value("${spring.profiles.active}") + private String activeEnv; + + @Value("${inference.geojson-dir}") + private String inferenceDir; + + // 0313 + @Transactional + public UUID asyncInferenceEnd() { + SaveInferenceAiDto dto = inferenceResultCoreService.getProcessing(); + if (dto == null) { + throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND); + } + + this.deleteInferenceEndAsync(dto); // 비동기 종료 호출 + + return dto.getUuid(); + } + + // 0313 + @Async("inferenceEndExecutor") + @Transactional + public void deleteInferenceEndAsync(SaveInferenceAiDto dto) { + Long batchId = dto.getBatchId(); + String url = batchUrl + "/" + batchId; + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(List.of(MediaType.APPLICATION_JSON)); + + try { + log.info("[추론 종료 비동기 시작] uuid={}, batchId={}", dto.getUuid(), batchId); + + ExternalCallResult result = + externalHttpClient.callLong(url, HttpMethod.DELETE, dto, headers, String.class); + + if (!result.success()) { + log.error("[추론 종료 실패] 외부 API 호출 실패. uuid={}, batchId={}", dto.getUuid(), batchId); + + SaveInferenceAiDto failRequest = new SaveInferenceAiDto(); + failRequest.setUuid(dto.getUuid()); + failRequest.setStatus(Status.END_FAIL.getId()); // TODO: 종료실패 상태 추가하는 게 맞는지? + failRequest.setUpdateUid(userUtil.getId()); + failRequest.setInferEndDttm(ZonedDateTime.now()); + inferenceResultCoreService.update(failRequest); + return; + } + + SaveInferenceAiDto request = new SaveInferenceAiDto(); + request.setStatus(Status.FORCED_END.getId()); + request.setUuid(dto.getUuid()); + request.setUpdateUid(userUtil.getId()); + request.setInferEndDttm(ZonedDateTime.now()); + inferenceResultCoreService.update(request); + + Long learnId = inferenceResultCoreService.getInferenceLearnIdByUuid(dto.getUuid()); + inferenceResultCoreService.upsertGeomData(learnId); + + log.info("[추론 종료 비동기 완료] uuid={}, batchId={}", dto.getUuid(), batchId); + + } catch (Exception e) { + log.error("[추론 종료 비동기 예외] uuid={}, batchId={}", dto.getUuid(), batchId, e); + } + } +} 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 9b7e5a29..5bb80056 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 @@ -63,7 +63,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -1034,63 +1033,4 @@ public class InferenceResultService { } return ""; } - - // 0313 - @Transactional - public UUID asyncInferenceEnd() { - SaveInferenceAiDto dto = inferenceResultCoreService.getProcessing(); - if (dto == null) { - throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND); - } - - this.deleteInferenceEndAsync(dto); // 비동기 종료 호출 - - return dto.getUuid(); - } - - // 0313 - @Async("inferenceEndExecutor") - @Transactional - public void deleteInferenceEndAsync(SaveInferenceAiDto dto) { - Long batchId = dto.getBatchId(); - String url = batchUrl + "/" + batchId; - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.setAccept(List.of(MediaType.APPLICATION_JSON)); - - try { - log.info("[추론 종료 비동기 시작] uuid={}, batchId={}", dto.getUuid(), batchId); - - ExternalCallResult result = - externalHttpClient.callLong(url, HttpMethod.DELETE, dto, headers, String.class); - - if (!result.success()) { - log.error("[추론 종료 실패] 외부 API 호출 실패. uuid={}, batchId={}", dto.getUuid(), batchId); - - SaveInferenceAiDto failRequest = new SaveInferenceAiDto(); - failRequest.setUuid(dto.getUuid()); - failRequest.setStatus(Status.END_FAIL.getId()); // TODO: 종료실패 상태 추가하는 게 맞는지? - failRequest.setUpdateUid(userUtil.getId()); - failRequest.setInferEndDttm(ZonedDateTime.now()); - inferenceResultCoreService.update(failRequest); - return; - } - - SaveInferenceAiDto request = new SaveInferenceAiDto(); - request.setStatus(Status.FORCED_END.getId()); - request.setUuid(dto.getUuid()); - request.setUpdateUid(userUtil.getId()); - request.setInferEndDttm(ZonedDateTime.now()); - inferenceResultCoreService.update(request); - - Long learnId = inferenceResultCoreService.getInferenceLearnIdByUuid(dto.getUuid()); - inferenceResultCoreService.upsertGeomData(learnId); - - log.info("[추론 종료 비동기 완료] uuid={}, batchId={}", dto.getUuid(), batchId); - - } catch (Exception e) { - log.error("[추론 종료 비동기 예외] uuid={}, batchId={}", dto.getUuid(), batchId, e); - } - } }