From 2cf4c84860146f94bb03c669d17b17d53dffc4df Mon Sep 17 00:00:00 2001 From: bjkim Date: Mon, 22 Sep 2025 13:13:41 +0900 Subject: [PATCH] =?UTF-8?q?[UPDATE]=20CreateRunRequest=20DTO=EC=99=80=20Pi?= =?UTF-8?q?pelineUploadService=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20?= =?UTF-8?q?=EB=B0=8F=20WebClient=EB=A1=9C=20Run=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/PipelineUploadController.java | 9 ++++- .../payload/request/CreateRunRequest.java | 37 +++++++++++++------ .../service/PipelineUploadService.java | 35 +++++++++--------- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/main/java/kr/re/etri/autoflow/controllers/PipelineUploadController.java b/src/main/java/kr/re/etri/autoflow/controllers/PipelineUploadController.java index c13e751..b3b1a55 100644 --- a/src/main/java/kr/re/etri/autoflow/controllers/PipelineUploadController.java +++ b/src/main/java/kr/re/etri/autoflow/controllers/PipelineUploadController.java @@ -76,18 +76,22 @@ public class PipelineUploadController { } @PostMapping("/runs") - @Operation(summary = "Kubeflow Run 생성", description = "Kubeflow에 Run을 생성합니다.") + @Operation( + summary = "Kubeflow Run 생성", + description = "Kubeflow에 Run을 생성합니다." + ) @ApiResponses({ @ApiResponse(responseCode = "200", description = "Run 생성 성공"), @ApiResponse(responseCode = "400", description = "display_name 필수"), @ApiResponse(responseCode = "500", description = "서버 오류") }) public ResponseEntity> createRun( - @Parameter @RequestBody CreateRunRequest runRequest + @RequestBody CreateRunRequest runRequest ) { try { Map result = pipelineUploadService.createRun(runRequest); return ResponseEntity.ok(result); + } catch (IllegalArgumentException e) { log.error("Invalid run request", e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) @@ -96,6 +100,7 @@ public class PipelineUploadController { "error", "Bad Request", "message", e.getMessage() )); + } catch (Exception e) { log.error("Run creation failed", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) diff --git a/src/main/java/kr/re/etri/autoflow/payload/request/CreateRunRequest.java b/src/main/java/kr/re/etri/autoflow/payload/request/CreateRunRequest.java index ecb239c..08795dc 100644 --- a/src/main/java/kr/re/etri/autoflow/payload/request/CreateRunRequest.java +++ b/src/main/java/kr/re/etri/autoflow/payload/request/CreateRunRequest.java @@ -1,41 +1,54 @@ package kr.re.etri.autoflow.payload.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import lombok.*; import java.util.Map; -@Data -@Schema(description = "Kubeflow Run 생성 요청 DTO") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Schema(description = "Kubeflow Run 생성 요청") public class CreateRunRequest { - @Schema(description = "Run 이름 (필수)", required = true, example = "Run of 435345 (5c7b9)") + @Schema(description = "Run 이름 (필수)", example = "Run of 435345 (5c7b9)") private String display_name; @Schema(description = "Run 설명", example = "테스트 Run") private String description; - @Schema(description = "파이프라인 버전 참조", required = true) + @Schema(description = "Pipeline Version Reference") private PipelineVersionReference pipeline_version_reference; - @Schema(description = "런 타임 구성") + @Schema(description = "Run Runtime Config") private RuntimeConfig runtime_config; @Schema(description = "서비스 계정", example = "pipeline-runner") private String service_account; - @Data - @Schema(description = "Pipeline Version Reference") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Schema(description = "Pipeline 버전 참조") public static class PipelineVersionReference { - @Schema(description = "파이프라인 ID", required = true) + @Schema(description = "Pipeline ID", example = "e701e230-9bc2-4104-819a-a59ff7501d69") private String pipeline_id; - @Schema(description = "파이프라인 버전 ID", required = true) + @Schema(description = "Pipeline Version ID", example = "cab9f077-7acd-4f68-a844-5aa9bb5635df") private String pipeline_version_id; } - @Data - @Schema(description = "Runtime Config") + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Schema(description = "Run Runtime Config") public static class RuntimeConfig { @Schema(description = "파라미터", example = "{}") private Map parameters; diff --git a/src/main/java/kr/re/etri/autoflow/service/PipelineUploadService.java b/src/main/java/kr/re/etri/autoflow/service/PipelineUploadService.java index 7bf154a..a7d54a3 100644 --- a/src/main/java/kr/re/etri/autoflow/service/PipelineUploadService.java +++ b/src/main/java/kr/re/etri/autoflow/service/PipelineUploadService.java @@ -14,7 +14,10 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; import java.io.IOException; import java.util.Map; @@ -29,6 +32,9 @@ public class PipelineUploadService { @Value("${kubeflow.url}") private String kubeflowBaseUrl; // 예: http://192.168.10.135:32473/ + private final WebClient webClient; + + /** * Pipeline 업로드 */ @@ -65,26 +71,21 @@ public class PipelineUploadService { * Run 생성 * runRequest에는 display_name, pipeline_version_reference, runtime_config 등이 포함되어야 함 */ -// PipelineUploadService.java public Map createRun(CreateRunRequest runRequest) { - try { - // URL 조립 - String url = kubeflowBaseUrl + "apis/v2beta1/runs"; - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - // DTO를 Map으로 변환해서 전송 - ObjectMapper objectMapper = new ObjectMapper(); - Map body = objectMapper.convertValue(runRequest, Map.class); - - HttpEntity> requestEntity = new HttpEntity<>(body, headers); - - ResponseEntity response = restTemplate.postForEntity(url, requestEntity, Map.class); + if (runRequest.getDisplay_name() == null || runRequest.getDisplay_name().isBlank()) { + throw new IllegalArgumentException("Run display_name cannot be empty"); + } - return response.getBody(); + try { + Mono responseMono = webClient.post() + .uri(kubeflowBaseUrl + "/apis/v2beta1/runs") + .contentType(MediaType.APPLICATION_JSON) + .body(BodyInserters.fromValue(runRequest)) + .retrieve() + .bodyToMono(Map.class); + + return responseMono.block(); // 동기 호출 } catch (Exception e) { - if (e instanceof IllegalArgumentException) throw e; throw new RuntimeException("Kubeflow Run creation failed", e); } }