추론실행 수정, develop pull 반영, 국유인 파일경로 dir 하드코딩 수정 #103
@@ -1,224 +0,0 @@
|
|||||||
package com.kamco.cd.kamcoback.inference.service;
|
|
||||||
|
|
||||||
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.geometry.GeoJsonFileWriter.Scene;
|
|
||||||
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
|
|
||||||
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
|
|
||||||
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto;
|
|
||||||
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto.pred_requests_areas;
|
|
||||||
import com.kamco.cd.kamcoback.model.dto.ModelMngDto.Basic;
|
|
||||||
import com.kamco.cd.kamcoback.model.dto.ModelMngDto.ModelType;
|
|
||||||
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
|
|
||||||
import com.kamco.cd.kamcoback.postgres.core.ModelMngCoreService;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
|
||||||
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.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@Log4j2
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class InferenceRunService {
|
|
||||||
private final ExternalHttpClient externalHttpClient;
|
|
||||||
private final MapSheetMngCoreService mapSheetMngCoreService;
|
|
||||||
private final ModelMngCoreService modelMngCoreService;
|
|
||||||
private final ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
@Value("${spring.profiles.active}")
|
|
||||||
private String profile;
|
|
||||||
|
|
||||||
@Value("${inference.url}")
|
|
||||||
private String inferenceUrl;
|
|
||||||
|
|
||||||
// TODO 이거 쓰는건가?
|
|
||||||
public void run(Integer compareYear, Integer targetYear, UUID modelUuid) {
|
|
||||||
|
|
||||||
List<String> compareList = mapSheetMngCoreService.getMapSheetMngHst(compareYear);
|
|
||||||
List<String> targetList = mapSheetMngCoreService.getMapSheetMngHst(targetYear);
|
|
||||||
|
|
||||||
log.info(
|
|
||||||
"hst list count compareList = {}, targetList = {}", compareList.size(), targetList.size());
|
|
||||||
|
|
||||||
Set<String> compareSet = new HashSet<>(compareList);
|
|
||||||
Set<String> targetSet = new HashSet<>(targetList);
|
|
||||||
|
|
||||||
long intersectionCount =
|
|
||||||
targetSet.stream()
|
|
||||||
.distinct()
|
|
||||||
.filter(compareSet::contains)
|
|
||||||
.count(); // compare와 target에 공통으로 존재하는 도협 수
|
|
||||||
|
|
||||||
long excludedTargetCount =
|
|
||||||
targetSet.stream()
|
|
||||||
.distinct()
|
|
||||||
.filter(s -> !compareSet.contains(s))
|
|
||||||
.count(); // target 에만 존재하는 도협 수 (compare 에는 없음)
|
|
||||||
|
|
||||||
long onlyCompareCount =
|
|
||||||
compareSet.stream()
|
|
||||||
.distinct()
|
|
||||||
.filter(s -> !targetSet.contains(s))
|
|
||||||
.count(); // compare 에만 존재하는 도협 수 (target 에는 없음)
|
|
||||||
|
|
||||||
log.info(
|
|
||||||
"""
|
|
||||||
===== MapSheet Year Comparison =====
|
|
||||||
target Total: {}
|
|
||||||
compare Total: {}
|
|
||||||
Intersection: {}
|
|
||||||
target Only (Excluded from compare): {}
|
|
||||||
compare Only: {}
|
|
||||||
====================================
|
|
||||||
""",
|
|
||||||
targetSet.size(),
|
|
||||||
compareSet.size(),
|
|
||||||
intersectionCount,
|
|
||||||
excludedTargetCount,
|
|
||||||
onlyCompareCount);
|
|
||||||
|
|
||||||
List<String> filteredTargetList =
|
|
||||||
targetSet.stream() // target 기준으로
|
|
||||||
.filter(compareSet::contains) // compare에 있는 도협만 남김
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
Scene modelComparePath = getSceneInference(compareYear.toString(), filteredTargetList, "", "");
|
|
||||||
|
|
||||||
Scene modelTargetPath = getSceneInference(targetYear.toString(), filteredTargetList, "", "");
|
|
||||||
|
|
||||||
// ai 서버에 전달할 파라미터 생성
|
|
||||||
pred_requests_areas predRequestsAreas = new pred_requests_areas();
|
|
||||||
predRequestsAreas.setInput1_year(compareYear);
|
|
||||||
predRequestsAreas.setInput2_year(targetYear);
|
|
||||||
predRequestsAreas.setInput1_scene_path(modelComparePath.getFilePath());
|
|
||||||
predRequestsAreas.setInput2_scene_path(modelTargetPath.getFilePath());
|
|
||||||
|
|
||||||
InferenceSendDto m1 = this.getModelInfo(modelUuid);
|
|
||||||
m1.setPred_requests_areas(predRequestsAreas);
|
|
||||||
|
|
||||||
// ai 추론 실행 api 호출
|
|
||||||
Long batchId = ensureAccepted(m1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Scene getSceneInference(
|
|
||||||
String yyyy, List<String> mapSheetNums, String mapSheetScope, String detectOption) {
|
|
||||||
return mapSheetMngCoreService.getSceneInference(
|
|
||||||
yyyy, mapSheetNums, mapSheetScope, detectOption);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 추론 AI API 호출
|
|
||||||
*
|
|
||||||
* @param dto
|
|
||||||
*/
|
|
||||||
private Long ensureAccepted(InferenceSendDto dto) {
|
|
||||||
|
|
||||||
if (dto == null) {
|
|
||||||
log.warn("not InferenceSendDto dto");
|
|
||||||
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1) 요청 로그
|
|
||||||
try {
|
|
||||||
log.info("Inference request dto={}", objectMapper.writeValueAsString(dto));
|
|
||||||
} catch (JsonProcessingException e) {
|
|
||||||
log.warn("Failed to serialize inference dto", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) HTTP 호출
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
||||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
|
||||||
|
|
||||||
ExternalCallResult<String> result =
|
|
||||||
externalHttpClient.call(inferenceUrl, HttpMethod.POST, dto, headers, String.class);
|
|
||||||
|
|
||||||
if (result.statusCode() < 200 || result.statusCode() >= 300) {
|
|
||||||
log.error("Inference API failed. status={}, body={}", result.statusCode(), result.body());
|
|
||||||
throw new CustomApiException("BAD_GATEWAY", HttpStatus.BAD_GATEWAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4) 응답 파싱
|
|
||||||
try {
|
|
||||||
List<Map<String, Object>> list =
|
|
||||||
objectMapper.readValue(result.body(), new TypeReference<>() {});
|
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
throw new IllegalStateException("Inference response is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
Object batchIdObj = list.get(0).get("batch_id");
|
|
||||||
if (batchIdObj == null) {
|
|
||||||
throw new IllegalStateException("batch_id not found in response");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Long.valueOf(batchIdObj.toString());
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to parse inference response. body={}", result.body(), e);
|
|
||||||
throw new CustomApiException("INVALID_INFERENCE_RESPONSE", HttpStatus.BAD_GATEWAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 모델정보 조회 dto 생성 후 반환
|
|
||||||
*
|
|
||||||
* @param uuid
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private InferenceSendDto getModelInfo(UUID uuid) {
|
|
||||||
|
|
||||||
Basic modelInfo = modelMngCoreService.findByModelUuid(uuid);
|
|
||||||
|
|
||||||
String cdModelPath = "";
|
|
||||||
String cdModelConfigPath = "";
|
|
||||||
String cdClsModelPath = "";
|
|
||||||
|
|
||||||
if (modelInfo.getCdModelPath() != null && modelInfo.getCdModelFileName() != null) {
|
|
||||||
cdModelPath =
|
|
||||||
Paths.get(modelInfo.getCdModelPath(), modelInfo.getCdModelFileName()).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelInfo.getCdModelConfig() != null && modelInfo.getCdModelConfigFileName() != null) {
|
|
||||||
cdModelConfigPath =
|
|
||||||
Paths.get(modelInfo.getCdModelConfig(), modelInfo.getCdModelConfigFileName()).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelInfo.getClsModelPath() != null && modelInfo.getClsModelFileName() != null) {
|
|
||||||
cdClsModelPath =
|
|
||||||
Paths.get(modelInfo.getClsModelPath(), modelInfo.getClsModelFileName()).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String modelType = "";
|
|
||||||
|
|
||||||
if (modelInfo.getModelType().equals(ModelType.G1.getId())) {
|
|
||||||
modelType = ModelType.G1.getId();
|
|
||||||
} else if (modelInfo.getModelType().equals(ModelType.G2.getId())) {
|
|
||||||
modelType = ModelType.G2.getId();
|
|
||||||
} else {
|
|
||||||
modelType = ModelType.G3.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
InferenceSendDto sendDto = new InferenceSendDto();
|
|
||||||
sendDto.setModel_version(modelInfo.getModelVer());
|
|
||||||
sendDto.setCd_model_path(cdModelPath);
|
|
||||||
sendDto.setCd_model_config(cdModelConfigPath);
|
|
||||||
sendDto.setCls_model_path(cdClsModelPath);
|
|
||||||
sendDto.setCls_model_version(modelInfo.getModelVer());
|
|
||||||
sendDto.setCd_model_type(modelType);
|
|
||||||
sendDto.setPriority(5.0);
|
|
||||||
return sendDto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user