AI retry, merged, classification 수동 호출 API 추가
This commit is contained in:
@@ -6,6 +6,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
|
||||
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient;
|
||||
import com.kamco.cd.kamcoback.config.resttemplate.ExternalHttpClient.ExternalCallResult;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceClassificationDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceMergedDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceSendDto;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -31,6 +33,15 @@ public class InferenceCommonService {
|
||||
@Value("${inference.url}")
|
||||
private String inferenceUrl;
|
||||
|
||||
@Value("${inference.merged-url}")
|
||||
private String mergedUrl;
|
||||
|
||||
@Value("${inference.batch-url}")
|
||||
private String batchUrl;
|
||||
|
||||
@Value("${inference.classification-url}")
|
||||
private String classificationUrl;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final ExternalHttpClient externalHttpClient;
|
||||
|
||||
@@ -108,4 +119,178 @@ public class InferenceCommonService {
|
||||
throw new CustomApiException("INVALID_INFERENCE_RESPONSE", HttpStatus.BAD_GATEWAY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MERGED API 호출 batch id를 리턴
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
public Long mergedPostProcessAccept(InferenceMergedDto.MergedRequestDto dto) {
|
||||
|
||||
if (dto == null) {
|
||||
log.warn("not MergedRequestDto dto");
|
||||
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
log.info("");
|
||||
log.info("====================================================================");
|
||||
log.info("[SEND MERGED] Merged request dto= {}", dto);
|
||||
log.info("====================================================================");
|
||||
log.info("");
|
||||
|
||||
// 1) 요청 로그
|
||||
try {
|
||||
log.debug("Inference request dto={}", objectMapper.writeValueAsString(dto));
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warn("Failed to serialize inference dto", e);
|
||||
}
|
||||
|
||||
// 2) HTTP 호출
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
||||
|
||||
// 3) MERGED 실행 API 호출
|
||||
ExternalCallResult<String> result =
|
||||
externalHttpClient.callLong(mergedUrl, HttpMethod.POST, dto, headers, String.class);
|
||||
|
||||
if (result.statusCode() < 200 || result.statusCode() >= 300) {
|
||||
log.error("Merge API failed. status={}, body={}", result.statusCode(), result.body());
|
||||
throw new CustomApiException("BAD_GATEWAY", HttpStatus.BAD_GATEWAY);
|
||||
}
|
||||
|
||||
// 4) 응답 파싱
|
||||
try {
|
||||
List<InferenceMergedDto.MergedResponseDto> list =
|
||||
objectMapper.readValue(
|
||||
result.body(), new TypeReference<List<InferenceMergedDto.MergedResponseDto>>() {});
|
||||
|
||||
if (list == null || list.isEmpty()) {
|
||||
throw new CustomApiException("NOT_FOUND", HttpStatus.NOT_FOUND, "Merged response is empty");
|
||||
}
|
||||
|
||||
InferenceMergedDto.MergedResponseDto batchIdObj = list.get(0);
|
||||
|
||||
if (batchIdObj.getBatch_id() == null) {
|
||||
throw new CustomApiException(
|
||||
"NOT_FOUND", HttpStatus.NOT_FOUND, "batch_id not found in response");
|
||||
}
|
||||
|
||||
return Long.valueOf(batchIdObj.getBatch_id().toString());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to parse merged response. body={}", result.body(), e);
|
||||
throw new CustomApiException("INVALID_INFERENCE_RESPONSE", HttpStatus.BAD_GATEWAY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* retry API 호출
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public int retryApiAccept(Long batchId) {
|
||||
|
||||
if (batchId == null) {
|
||||
log.warn("not batchId");
|
||||
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
log.info("");
|
||||
log.info("====================================================================");
|
||||
log.info("[SEND INFERENCE] batchId = {}", batchId);
|
||||
log.info("====================================================================");
|
||||
log.info("");
|
||||
|
||||
// 1) 요청 로그
|
||||
try {
|
||||
log.debug("batchId={}", objectMapper.writeValueAsString(batchId));
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warn("Failed to serialize batchId", e);
|
||||
}
|
||||
|
||||
// 2) HTTP 호출
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
||||
|
||||
// 3) retry API URL
|
||||
String url = batchUrl + "/" + batchId + "/retry";
|
||||
|
||||
// 4) 추론 실행 API 호출
|
||||
ExternalCallResult<String> result =
|
||||
externalHttpClient.callLong(url, HttpMethod.POST, null, headers, String.class);
|
||||
|
||||
return result.statusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* classification API 호출 batchId를 리턴
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public Long classficationApiAccept(InferenceClassificationDto.ClassificationRequestDto dto) {
|
||||
|
||||
if (dto == null) {
|
||||
log.warn("not ClassificationRequestDto dto");
|
||||
throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
log.info("");
|
||||
log.info("====================================================================");
|
||||
log.info("[SEND MERGED] Classification request dto= {}", dto);
|
||||
log.info("====================================================================");
|
||||
log.info("");
|
||||
|
||||
// 1) 요청 로그
|
||||
try {
|
||||
log.debug("Classification request dto={}", objectMapper.writeValueAsString(dto));
|
||||
} catch (JsonProcessingException e) {
|
||||
log.warn("Failed to serialize inference dto", e);
|
||||
}
|
||||
|
||||
// 2) HTTP 호출
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
|
||||
|
||||
// 3) MERGED 실행 API 호출
|
||||
ExternalCallResult<String> result =
|
||||
externalHttpClient.callLong(classificationUrl, HttpMethod.POST, dto, headers, String.class);
|
||||
|
||||
if (result.statusCode() < 200 || result.statusCode() >= 300) {
|
||||
log.error(
|
||||
"Classification API failed. status={}, body={}", result.statusCode(), result.body());
|
||||
throw new CustomApiException("BAD_GATEWAY", HttpStatus.BAD_GATEWAY);
|
||||
}
|
||||
|
||||
// 4) 응답 파싱
|
||||
try {
|
||||
List<InferenceClassificationDto.MergedResponseDto> list =
|
||||
objectMapper.readValue(
|
||||
result.body(),
|
||||
new TypeReference<List<InferenceClassificationDto.MergedResponseDto>>() {});
|
||||
|
||||
if (list == null || list.isEmpty()) {
|
||||
throw new CustomApiException(
|
||||
"NOT_FOUND", HttpStatus.NOT_FOUND, "Classification response is empty");
|
||||
}
|
||||
|
||||
InferenceClassificationDto.MergedResponseDto batchIdObj = list.get(0);
|
||||
|
||||
if (batchIdObj.getBatch_id() == null) {
|
||||
throw new CustomApiException(
|
||||
"NOT_FOUND", HttpStatus.NOT_FOUND, "batch_id not found in response");
|
||||
}
|
||||
|
||||
return Long.valueOf(batchIdObj.getBatch_id().toString());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to parse Classification response. body={}", result.body(), e);
|
||||
throw new CustomApiException("INVALID_INFERENCE_RESPONSE", HttpStatus.BAD_GATEWAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package com.kamco.cd.kamcoback.inference;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.inference.service.InferenceCommonService;
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceClassificationDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceMergedDto;
|
||||
import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto;
|
||||
import com.kamco.cd.kamcoback.inference.service.InferenceManualService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
@@ -10,9 +15,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "추론결과 데이터 생성", description = "추론결과 데이터 생성 API")
|
||||
@RestController
|
||||
@@ -21,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class InferenceManualApiController {
|
||||
|
||||
private final InferenceManualService inferenceManualService;
|
||||
private final InferenceCommonService inferenceCommonService;
|
||||
|
||||
@Operation(summary = "추론 결과로 추론 목록 및 shp 생성", description = "추론 결과로 추론 목록 및 shp 생성")
|
||||
@ApiResponses(
|
||||
@@ -40,4 +45,83 @@ public class InferenceManualApiController {
|
||||
public void saveTesting(List<Long> batchIds) {
|
||||
inferenceManualService.saveResultsTesting(batchIds);
|
||||
}
|
||||
|
||||
@Operation(summary = "AI MERGED API 호출", description = "AI MERGED API 호출")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "검색 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = Page.class))),
|
||||
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@GetMapping("/merged-api")
|
||||
public ApiResponseDto<Long> mergedPostProcessAccept(
|
||||
@Parameter(description = "batch_ids", example = "2026,2027") @RequestParam
|
||||
List<Integer> batchIds,
|
||||
@Parameter(description = "min_area", example = "10") @RequestParam Integer minArea) {
|
||||
|
||||
InferenceMergedDto.MergedRequestDto request = new InferenceMergedDto.MergedRequestDto();
|
||||
request.setBatch_ids(batchIds);
|
||||
request.setMin_area(Float.valueOf(minArea));
|
||||
|
||||
// MERGED 실행 api 호출
|
||||
Long batchId = inferenceCommonService.mergedPostProcessAccept(request);
|
||||
return ApiResponseDto.ok(batchId);
|
||||
}
|
||||
|
||||
@Operation(summary = "AI Classification API 호출", description = "AI Classification API 호출")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "검색 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = Page.class))),
|
||||
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@GetMapping("/classification-api")
|
||||
public ApiResponseDto<Long> classficationApiAccept(
|
||||
@Parameter(description = "batch_ids", example = "2026,2027") @RequestParam
|
||||
List<Integer> batchIds) {
|
||||
|
||||
InferenceClassificationDto.ClassificationRequestDto request =
|
||||
new InferenceClassificationDto.ClassificationRequestDto();
|
||||
request.setBatch_ids(batchIds);
|
||||
request.setCls_model_path("/data/ckpt/model/v6-cls-checkpoints/yolov8_6th-6m.pt");
|
||||
request.setCls_model_version("testing-re-cls");
|
||||
|
||||
// Classification 실행 api 호출
|
||||
Long batchId = inferenceCommonService.classficationApiAccept(request);
|
||||
return ApiResponseDto.ok(batchId);
|
||||
}
|
||||
|
||||
@Operation(summary = "AI Retry API 호출", description = "AI Retry API 호출")
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "검색 성공",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = Page.class))),
|
||||
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||
})
|
||||
@GetMapping("/retry-api")
|
||||
public ApiResponseDto<Integer> retryApiAccept(
|
||||
@Parameter(description = "batch_id", example = "2026") @RequestParam Long batchId) {
|
||||
|
||||
// retryApiAccept 실행 api 호출
|
||||
int statusCode = inferenceCommonService.retryApiAccept(batchId);
|
||||
return ApiResponseDto.ok(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.kamco.cd.kamcoback.inference.dto;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class InferenceClassificationDto {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public static class ClassificationRequestDto {
|
||||
private List<Integer> batch_ids;
|
||||
private String cls_model_path;
|
||||
private String cls_model_version;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public static class MergedResponseDto {
|
||||
private Integer id;
|
||||
private String scene_id;
|
||||
private String model_name;
|
||||
private String status;
|
||||
private Integer batch_id;
|
||||
private ZonedDateTime created_at;
|
||||
private ZonedDateTime started_at;
|
||||
private ZonedDateTime finished_at;
|
||||
private String worker_id;
|
||||
private String error_message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.kamco.cd.kamcoback.inference.dto;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import lombok.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class InferenceMergedDto {
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public static class MergedRequestDto {
|
||||
|
||||
private List<Integer> batch_ids;
|
||||
private Float min_area;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public static class MergedResponseDto {
|
||||
|
||||
private Integer id;
|
||||
private String scene_id;
|
||||
private String model_name;
|
||||
private String status;
|
||||
private Integer batch_id;
|
||||
private ZonedDateTime created_at;
|
||||
private ZonedDateTime started_at;
|
||||
private ZonedDateTime finished_at;
|
||||
private String worker_id;
|
||||
private String error_message;
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,8 @@ inference:
|
||||
jar-path-v2: ${inference.nfs}/repo/jar/shp-exporter-v2.jar
|
||||
inference-server-name: server1,server2,server3,server4
|
||||
output-dir: ${inference.nfs}/model_output/export
|
||||
merged-url: http://192.168.2.183:8000/merge-postprocess
|
||||
classification-url: http://192.168.2.183:8000/reclassification
|
||||
|
||||
gukyuin:
|
||||
#url: http://localhost:8080
|
||||
|
||||
@@ -75,12 +75,14 @@ file:
|
||||
|
||||
inference:
|
||||
nfs: C:/Users/gypark/kamco-nfs
|
||||
url: http://10.100.0.11:8000/jobs
|
||||
batch-url: http://10.100.0.11:8000/batches
|
||||
url: http://192.168.2.183:8000/jobs
|
||||
batch-url: http://192.168.2.183:8000/batches
|
||||
jar-path: jar/shp-exporter.jar
|
||||
jar-path-v2: jar/shp-exporter-v2.jar
|
||||
inference-server-name: server1,server2,server3,server4
|
||||
output-dir: ${inference.nfs}/model_output/export
|
||||
merged-url: http://192.168.2.183:8000/merge-postprocess
|
||||
classification-url: http://192.168.2.183:8000/reclassification
|
||||
|
||||
gukyuin:
|
||||
#url: http://localhost:8080
|
||||
|
||||
@@ -99,6 +99,8 @@ inference:
|
||||
jar-path-v2: ${inference.nfs}/repo/jar/shp-exporter-v2.jar
|
||||
inference-server-name: server1,server2,server3,server4
|
||||
output-dir: ${inference.nfs}/model_output/export
|
||||
merged-url: http://172.16.4.56:8000/merge-postprocess
|
||||
classification-url: http://172.16.4.56:8000/reclassification
|
||||
|
||||
gukyuin:
|
||||
url: http://127.0.0.1:5301
|
||||
|
||||
Reference in New Issue
Block a user